-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlinkedListReversal.py
More file actions
339 lines (252 loc) · 6.92 KB
/
linkedListReversal.py
File metadata and controls
339 lines (252 loc) · 6.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# Reverse a LinkedList
'''
Given the head of a Singly LinkedList, reverse the LinkedList.
Write a function to return the new head of the reversed LinkedList.
'''
from __future__ import print_function
from collections import deque
from logging import _Level
import queue
from turtle import left
from unittest import skip
class Node:
def __init__(self, value, next=None):
self.value = value
self.next = next
def print_list(self):
temp = self
while temp is not None:
print(temp.value, end=" ")
temp = temp.next
print()
def reverse(head):
p1 = None
p2 = head
while p2 != None:
p3 = p2.next
p2.next = p1
p1 = p2
p2 = p3
return p1
def main():
head = Node(2)
head.next = Node(4)
head.next.next = Node(6)
head.next.next.next = Node(8)
head.next.next.next.next = Node(10)
print("Nodes of original LinkedList are: ", end='')
head.print_list()
result = reverse(head)
print("Nodes of reversed LinkedList are: ", end='')
result.print_list()
main()
#Reverse a Sub-list (medium)
'''
Given the head of a LinkedList and two positions p and q,
reverse the LinkedList from position p to q.
'''
def reverse_sub_list(head, p, q):
# TODO: Write your code here
leftNode = head
i = 1
while i < p - 1:
leftNode = leftNode.next
i += 1
if p == 1:
startNode = leftNode
else:
startNode = leftNode.next
endNode = head
j = 1
while j < q:
endNode = endNode.next
j += 1
if endNode.next is None:
rightNode = endNode
else:
rightNode = endNode.next
p1 = None
p2 = startNode
while p1 != endNode:
p3 = p2.next
p2.next = p1
p1 = p2
p2 = p3
if startNode != leftNode:
leftNode.next = endNode
if endNode != rightNode:
# the start of the sublist - when reversed, this is the end of the sublist.
# We need to connect the end with the right node
startNode.next = rightNode
if p == 1:
return p1
else:
return head
def main():
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
print("Nodes of original LinkedList are: ", end='')
head.print_list()
result = reverse_sub_list(head, 2, 4)
print("Nodes of reversed LinkedList are: ", end='')
result.print_list()
main()
# Reverse every K-element Sub-list (medium)
'''
Given the head of a LinkedList and a number k,
reverse every k sized sub-list starting from the head.
If, in the end, you are left with a sub-list with less than k elements, reverse it too.
'''
# start is the start node of the sublist
def reverse_sublist_size_k(start, k, previous):
p1 = None
p2 = start
while k > 0 and p2 != None:
p3 = p2.next
p2.next = p1
p1 = p2
p2 = p3
k -= 1
start.next = p3
if previous != None:
previous.next = p1
return p3, start
def reverse_every_k_elements(head, k):
# TODO: Write your code here
newHead = head
i = 1
while i < k:
newHead = newHead.next
i+=1
currentNode = head
previousEnd = None
while currentNode != None:
currentNode, previousEnd = reverse_sublist_size_k(currentNode, k, previousEnd)
return newHead
def main():
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
head.next.next.next.next.next.next = Node(7)
head.next.next.next.next.next.next.next = Node(8)
print("Nodes of original LinkedList are: ", end='')
head.print_list()
result = reverse_every_k_elements(head, 3)
print("Nodes of reversed LinkedList are: ", end='')
result.print_list()
main()
# Reverse alternating K-element Sub-list
'''
Given the head of a LinkedList and a number k,
reverse every alternating k sized sub-list starting from the head.
If, in the end, you are left with a sub-list with less than k elements, reverse it too.
'''
def reverseList(head, previous,k,skip):
i = 1
if skip == True:
while i <= k and head is not None:
head = head.next
i += 1
previous = previous.next
skip = False
return previous, head, skip
p1 = None
p2 = head
while i <= k and p2 != None:
p3 = p2.next
p2.next = p1
p1 = p2
p2 = p3
i += 1
# connect the left side of the linkedlist to reversed sublist if exists
if previous != None:
previous.next = p1
#connect the reversed sublist to right side of the linked list
head.next = p3
if not skip:
skip = True
else:
skip = False
# head is the last node of the reversed linkedlist and p3 is the head of the next sublist
return head, p3, skip
def reverse_alternate_k_elements(head, k):
newHead = head
i = 1
while i < k:
newHead = newHead.next
i += 1
skip = False
current = head
previous = None
while current:
previous, current, skip = reverseList(current,previous,k,skip)
return newHead
def main():
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
head.next.next.next.next.next.next = Node(7)
head.next.next.next.next.next.next.next = Node(8)
print("Nodes of original LinkedList are: ", end='')
head.print_list()
result = reverse_alternate_k_elements(head, 2)
print("Nodes of reversed LinkedList are: ", end='')
result.print_list()
main()
# Rotate a LinkedList (medium)
'''
Given the head of a Singly LinkedList and a number k,
rotate the LinkedList to the right by k nodes.
'''
from __future__ import print_function
class Node:
def __init__(self, value, next=None):
self.value = value
self.next = next
def print_list(self):
temp = self
while temp is not None:
print(temp.value, end=" ")
temp = temp.next
print()
def rotate(head, rotations):
if head is None or head.next is None or rotations <= 0:
return head
# find the length and the last node of the list
last_node = head
list_length = 1
while last_node.next is not None:
last_node = last_node.next
list_length += 1
last_node.next = head # connect the last node with the head to make it a circular list
rotations %= list_length # no need to do rotations more than the length of the list
skip_length = list_length - rotations
last_node_of_rotated_list = head
for i in range(skip_length - 1):
last_node_of_rotated_list = last_node_of_rotated_list.next
# 'last_node_of_rotated_list.next' is pointing to the sub-list of 'k' ending nodes
head = last_node_of_rotated_list.next
last_node_of_rotated_list.next = None
return head
def main():
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
print("Nodes of original LinkedList are: ", end='')
head.print_list()
result = rotate(head, 3)
print("Nodes of rotated LinkedList are: ", end='')
result.print_list()
main()