Skip to content

Commit c54752a

Browse files
committed
Update the solution of 92. Reverse Linked List II
1 parent 3972c72 commit c54752a

File tree

2 files changed

+52
-68
lines changed

2 files changed

+52
-68
lines changed

leetcode/322.coin-change.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ fun coinChange(coins: IntArray, amount: Int): Int {
145145

146146
private fun knapsack(coins: IntArray, amount: Int): Int {
147147
val dp = Array(coins.size + 1) { _ -> IntArray(amount + 1) }
148+
// It's fine to exhange the order of the loops.
148149
for (i in 0..coins.size) {
149150
for (a in 0..amount) {
150151
dp[i][a] = if (a == 0) {

leetcode/92.reverse-linked-list-ii.md

Lines changed: 51 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,85 @@
22

33
**Idea!** We find the part to reverse and the before / after node of reverse list, reuse modified `reverseLinkedList(node)` with length to reverse, and relink the before / after node pointer to correct.
44

5+
For example:
6+
57
```js
68
1 -> 2 -> 3 -> 4 -> 5
79
left = 2, right = 4
810

9-
// Traverse list to find the before / after pointer
10-
before = 1
11-
after = 5
11+
// Traverse list to find the node of before left, after right and last node of reversed list
12+
beforeLeft = 1
13+
afterRight = 5
14+
last = 2
1215

1316
// Reverse from left to right
1417
reversedHead = reverseLinkedList(2 -> 3 -> 4), return 4
1518

1619
// Relink before and after pointer to reverse list
17-
before -> reversedHead -> ... -> after
20+
beforeLeft -> reversedHead -> ... -> last -> afterRight
1821
```
1922

2023
```kotlin
2124
fun reverseBetween(head: ListNode?, left: Int, right: Int): ListNode? {
22-
// Pointers before and after reverse part
23-
var before: ListNode? = null
24-
var after: ListNode? = null
25-
// Pointer to start reverse
26-
var start: ListNode? = null
25+
if (head == null) return null
2726

28-
// Traverse the list to locate the above pointers
29-
var i = 1
30-
var previous: ListNode? = null
27+
// add sentinel
28+
val sentinel = ListNode(0)
29+
sentinel.next = head
30+
31+
// iterate to locate the left, before left, right, after right node.
32+
var beforeLeft: ListNode? = null
33+
var afterRight: ListNode? = null
34+
// The last node after reversing
35+
var last: ListNode? = null
36+
var previous: ListNode? = sentinel
3137
var current: ListNode? = head
38+
var i = 1
3239
while (current != null) {
3340
if (i == left) {
34-
before = previous
35-
start = current
41+
beforeLeft = previous
42+
last = current
3643
}
37-
if (i == right + 1) {
38-
after = current
44+
if (i == right) {
45+
afterRight = current.next
46+
break
3947
}
40-
i++
48+
4149
previous = current
4250
current = current.next
51+
i++
4352
}
4453

45-
// Reverse from left to right
46-
var reversedHead = reverseLinkedList(start, right - left)
54+
// reverse(left, right), return new head after reversed.
55+
val newHead = reverse(last, current)
56+
// val newHead = reverseLinkedList(start, right - left)
57+
// val newHead = reverse(leftNode, right - left + 1)
4758

48-
// Relink the before pointer
49-
before?.next = reversedHead
59+
// relink before left node to new head.
60+
beforeLeft?.next = newHead
61+
62+
// relink the last node of revsered list to the node after right.
63+
last?.next = afterRight
5064

65+
// return sentinel.next
66+
return sentinel.next
67+
}
5168

52-
// Find the last node of reverse list
53-
var lastNode: ListNode? = reversedHead
54-
while (lastNode?.next != null) {
55-
lastNode = lastNode.next
56-
}
57-
// Relink the after pointer
58-
lastNode?.next = after
69+
private fun reverse(head: ListNode?, last: ListNode?): ListNode? {
70+
var previous: ListNode? = null
71+
var current: ListNode? = head
72+
while (current != null && previous != last) {
73+
val next = current.next
74+
current.next = previous
5975

60-
// left == 1 means we reverse from start, the head will change.
61-
return if (left == 1) reversedHead
62-
else head
76+
previous = current
77+
current = next
78+
}
79+
return previous
6380
}
6481

65-
private fun reverseLinkedList(node: ListNode?, length: Int): ListNode? {
82+
// Alternative implementation of reverse by length
83+
private fun reverse(node: ListNode?, length: Int): ListNode? {
6684
var i = 0
6785
var previous: ListNode? = null
6886
var current: ListNode? = node
@@ -76,43 +94,8 @@ private fun reverseLinkedList(node: ListNode?, length: Int): ListNode? {
7694
}
7795
return previous
7896
}
79-
```
80-
81-
### More Concise
82-
For the example: `1 -> 2 -> 3 -> 4 -> 5`, left = 2, right = 4, we have to find `1 -> 2` and `4 -> 5`, and reverse between `2 -> 3 -> 4` and relink `1` to the new head of reversed list and relink the last node of reversed list to `5`.
83-
84-
```kotlin
85-
fun reverseBetween(head: ListNode?, left: Int, right: Int): ListNode? {
86-
// We introduce sentinel for help
87-
val sentinel = ListNode(-1)
88-
sentinel.next = head
89-
90-
// Looking for 1 -> 2
91-
var nodeBeforeLeft: ListNode? = sentinel
92-
var leftNode: ListNode? = head
93-
var i = 1
94-
while (i < left) {
95-
nodeBeforeLeft = leftNode
96-
leftNode = leftNode?.next
97-
i++
98-
}
99-
// Lookin for 4 -> 5
100-
var rightNode: ListNode? = nodeBeforeLeft
101-
var nodeAfterRight: ListNode? = rightNode?.next
102-
while (i <= right) {
103-
rightNode = rightNode?.next
104-
nodeAfterRight = rightNode?.next
105-
i++
106-
}
107-
108-
val reverseHead = reverse(leftNode, right - left + 1)
109-
// Relink 1 -> reversed list
110-
nodeBeforeLeft?.next = reverseHead
111-
// Relink reversed list -> 5
112-
leftNode?.next = nodeAfterRight
113-
return sentinel.next
114-
}
11597

98+
// Alternative implementation of reverse by counting
11699
private fun reverse(start: ListNode?, count: Int): ListNode? {
117100
var previous: ListNode? = null
118101
var current: ListNode? = start

0 commit comments

Comments
 (0)