linked list
]
Leetcode 0143. Reorder List
https://leetcode.com/problems/reorder-list
If you never solved singly linked lists problems before, or you do not have a lot of experience, this problem can be quite difficult. However if you already know all the tricks, it is not difficult at all. Let us first try to understand what we need to do. For list [1,2,3,4,5,6,7] we need to return [1,7,2,6,3,5,4]. We can note, that it is actually two lists [1,2,3,4] and [7,6,5], where elements are interchange. So, to succeed we need to do the following steps:
- Find the middle of or list - be careful, it needs to work properly both for even and for odd number of nodes. For this we can either just count number of elements and then divide it by to, and do two traversals of list. Or we can use
slow/fastiterators trick, whereslowmoves with speed1andfastmoves with speed2. Then whenfastreches the end,slowwill be in the middle, as we need. - Reverse the second part of linked list. Again, if you never done it before, it can be quite painful, please read oficial solution to problem 206. Reverse Linked List. The idea is to keep three pointers:
prev, curr, nexttstand for previous, current and next and change connections in place. Do not forget to useslow.next = None, in opposite case you will have list with loop. - Finally, we need to merge two lists, given its heads. These heads are denoted by
headandprev, so for simplisity I createdhead1andhead2variables. What we need to do now is to interchange nodes: we puthead2as next element ofhead1and then say thathead1is nowhead2andhead2is previoushead1.next. In this way we do one step for one of the lists and rename lists, so next time we will take element fromhead2, then rename again and so on.
Complexity: Time complexity is O(n), because we first do O(n) iterations to find middle, then we do O(n) iterations to reverse second half and finally we do O(n) iterations to merge lists. Space complexity is O(1).
class Solution:
def reorderList(self, head):
#step 1: find middle
if not head: return []
slow, fast = head, head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
#step 2: reverse second half
prev, curr = None, slow.next
while curr:
nextt = curr.next
curr.next = prev
prev = curr
curr = nextt
slow.next = None
#step 3: merge lists
head1, head2 = head, prev
while head2:
nextt = head1.next
head1.next = head2
head1 = head2
head2 = nextt
If you like the solution, you can upvote it on leetcode discussion section: Problem 0143