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
curpointing 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
curpointer pointing to thedummyso we can add the nodes that are pop from the stack, and we need anexpointer 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
dummynode in front of the input node’s head, and need aprepointer that points to dummy node,lastpointer 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 acurpointing to node2and make it become the first node. Then,curpointing to node3and make node3pointing to the beginning of the node, and we are done reversing. Also, before we start reverse, we should have atailnode that points to1because it will eventually be the tail of this sublist. Finally, whencurequals tolast, we are done. Before we checking the next $k$ nodes, we need to set thepretotailand 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
nexpointer 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 | |