Description:
Given the head of a singly linked list and two integers left and right where left <= right, reverse the nodes of the list from position left to position right, and return the reversed list.
Input: head = [1,2,3,4,5], left = 2, right = 4
Output: [1,4,3,2,5]
Solution:
we may consider the Reverse part of Linked list question in two part. The section that has to be inverted has the same answer as Leetcode question 206 (Reverse Linked List), and the other part does not need to be changed.
1->2->3->4->5->
1-> 2->3->4-> 5->
1-> 4->3->2-> 5->
1->4->3->2->5->
The special scenario in this query occurs when the left index is 1, since the result head of linked list is changed to the one of reversed section.
reverse(1,4) (head)1->2->3->4->5->
reverse(1,4) (the head of reversed)4->3->2->1(the head of original one)->5->
As we divide the query into two parts, we must record the node before the left one(prev) and the node after the right one(current). When we have finished partially reversing, we simply need to make the node before the left point to the head of reversed section and the tail of reversed part point to the node after the right.
There maybe some more succinct and optimal solutions. I will update this blog when I’ve reviewed them.
fun reverseBetween(head: ListNode?, left: Int, right: Int): ListNode? {
var prev: ListNode? = null
var current = head
var index = 1
while (index < left) {
// Recording the one before the left one, so it can point to the reversed section.
if (index == left - 1) {
prev = current
}
current = current?.next
index++
}
// Recording the tail of reversed section, so it can point to the latter part of the linked list.
val reverseTail: ListNode? = current
// reversing linked list
var reversePrev: ListNode? = null
while (index <= right) {
val temp = current?.next
current?.next = reversePrev
reversePrev = current
current = temp
index++
}
//current is the next node of the right index, It does not matter if current is null.
reverseTail?.next = current
prev?.next = reversePrev
// Detemine which node should be used as the new head of the result.
return if (left != 1) {
head
} else {
reversePrev
}
}