Link: https://leetcode.com/problems/reverse-nodes-in-k-group/
Solution:
Topics: linked list, recursion
Intuition
This is a fantastic linked list problem! Reversing a linked list is trivial but reversing k
long partitions and connecting them together is quite tricky.
Lets look at this problem from a high level before going into the approach:
[1,2,3,4], k = 2
[1,2,3,4]
^ ^ this partition gets reversed
[1,2,3,4]
^ ^ and this partition gets reversed
resulting in:
[2,1,4,3]
This is simple enough, but observe that 1 MUST point to 4...so BEFORE [1,2] can be reversed, we must reverse [3,4]!
Ergo, the last partitions of length k
must be reversed before preceding ones, thus recursion is the natural choice!
This is how:
[1,2,3,4], k = 2
reverse([1,2]) ----> [2,1] is the result
1.next = reverse([3,4])
return 2
Essentially, we set the new tail.next
(of the reversed list) to the reverse of the next partition, and then return the new head
!
There is one notable edge case. If there are less than k
nodes in the last partition, we must return it unmodified. This will require simply making sure that there are at least k
nodes remaining in the current partition before reversing. Technically this make the problem o(2n)
time, but thats ok.
Also, if k == 1
, just return the head of the list…no reversing required.
Implementation
Review 1
Very annoying problem! I got to the solution but it took me a while! Basically, the only way to solve something like this is with recursion. Why? Because if we reverse a portion of the list, we cannot know what the next node will be because that node represents the start of the next partition that must also be reversed…so that node should be the tail of the next, reversed partition.
Lets look at what happens if we try to do this iteratively:
list = [1,2,3,1,2,3] k = 3
[3,2,1][1,2,3] -> reverse the first partition
| |
--------
Acually we cannot reverse the first partiton before reversing the second because notice that the first 1 must eventually point to the second 3!
Technically this can be done iteratively but you would have to convert into a doubly linked list...probably not recommended.
I came up with a slightly different approach from above. Basically i stored the nodes in a list and if len(list) == k
, I reversed everything in the list and reset the list. This is using o(k)
memory, but it will be twice as fast as the above implementation, since we are not checking if k
nodes are available every increment. However the above is way simpler, so I would stick to it.