Problem
Given a linked list, reverse the nodes of a linked list $k$ at a time and return its modified list.
$k$ is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of $k$ then left-out nodes in the end should remain as it is.
Example:
Given this linked list: 1->2->3->4->5
For $k$ = 2, you should return: 2->1->4->3->5
For $k$ = 3, you should return: 3->2->1->4->5
Note:
- Only constant extra memory is allowed.
- You may not alter the values in the list’s nodes, only nodes itself may be changed.
Explanation 1
-
We want to reverse $k$ ListNode each time, and to do the reverse, we can use a $stack$ data structure because it’s last in first out.
-
To keep track of the next $k$ ListNode, we can create a dummy node in front of the head and a pointer
cur
pointing to the dummy node. Then we can reference the next $k$ ListNode by usingcur.next; cur = cur.next
. After reversing the next $k$ node, we need to point it back to the $k+1$ node. For example, when $k$ is 3:1
2
3
4
5
6
7
8
9
10
11dummy->1->2->3->4->5 Stack: [3] [2] [1] dummy->3->2->1->4->5
-
So, we need a
cur
pointer pointing to thedummy
so we can add the nodes that are pop from the stack, and we need anex
pointer pointing to the 4, so after poping, we can link the 4 back.
Solution 1
1 |
|
Explanation 2
-
The last solution use a stack that costs $O(n)$ space. This time, we don’t need extra space. Like the last solution, we need to create a
dummy
node in front of the input node’s head, and need apre
pointer that points to dummy node,last
pointer that points to the $k+1$’s node.1
2
3dummy -> 1 -> 2 -> 3 -> 4 -> 5 | | pre last
-
Now, we need to reverse the nodes between pre (exclusive) and last (exclusive), we can think of this as a sublist.
-
We should starts from the second node in this sublist, which is node
2
. We have acur
pointing to node2
and make it become the first node. Then,cur
pointing to node3
and make node3
pointing to the beginning of the node, and we are done reversing. Also, before we start reverse, we should have atail
node that points to1
because it will eventually be the tail of this sublist. Finally, whencur
equals tolast
, we are done. Before we checking the next $k$ nodes, we need to set thepre
totail
and start moving thelast
$k$ steps next.1
2
3
4
5
6
7
8
9
10
11dummy -> 1 -> 2 -> 3 -> 4 -> 5 | | | | pre tail cur last dummy -> 2 -> 1 -> 3 -> 4 -> 5 | | | | pre tail cur last dummy -> 3 -> 2 -> 1 -> 4 -> 5 | | | pre tail (cur)last
-
For example, in the above second step, we want to move 2 in front of 1, we can set the
nex
pointer pointing to 3, then do the following:1
2
3
4
5
6
7
8
9
10
11
12dummy -> 1 -> 2 -> 3 -> 4 -> 5 | | | | | pre tail cur nex last cur.next = pre.next 2 -> 1 -> 2 -> 3 -> 4 -> 5 pre.next = cur dummy -> 2 -> 1 -> 2 -> 3 -> 4 -> 5 tail.next = nex dummy -> 2 -> 1 -> 3 -> 4 -> 5
Solution 2
1 |
|