# 92.反转链表 II
# 题目描述
给你单链表的头指针 head 和两个整数 left 和 right,其中 left <= right。请你反转从位置 left 到位置 right 的链表节点,返回反转后的链表。
# 解题思路
# 思路一
- 遍历链表,在没有到达指定反转位置时,继续遍历,直到到达指定反转位置
- 达到指定反转位置时,记录当前节点,并开始反转
- 反转过程中将在反转范围中的下一个节点(当前正在处理的节点)指向反转后头结点的下一个节点,并更新反转后头结点的下一个节点为当前节点
- 反转结束后,将进入反转节点前的一个节点执行反转链表的头节点,并将反转节点的尾结点指向当前处理的节点
- 继续遍历后续节点,直到链表遍历结束
var reverseBetween = function (head, left, right) {
if (!head) return null
let newHead = {}
let prev = newHead
let current = head
let i = 1 // 当前节点位置
let reverseHead = {}
let reverseTail = {}
while (current) {
if (i >= left && i <= right) {
if (reverseHead.next) {
let next = current.next
current.next = reverseHead.next
reverseHead.next = current
current = next
} else {
reverseHead.next = current
reverseTail.next = current
current = current.next
}
i++
continue
}
if (reverseHead.next) {
prev.next = reverseHead.next
reverseTail.next.next = current
reverseHead.next = null // 标识已经处理
} else {
prev.next = current
}
prev = current
current = current.next
i++
}
if (reverseHead.next) {
prev.next = reverseHead.next
reverseTail.next.next = current
}
return newHead.next
}
# 思路二
- 遍历链表,在没有到达指定反转位置时,继续遍历,直到到达指定反转位置
- 达到指定反转位置时,记录当前节点,继续遍历
- 反转过程中,每次将反转范围内当前正在处理的节点插入到反转链表的头结点之前
- 退出反转范围时,将反转范围的未节点执行当前正在处理的节点
- 继续遍历后续节点,直到链表遍历结束
var reverseBetween = function (head, left, right) {
if (!head) return null
let newHead = {}
let prev = newHead
let current = head
let i = 1 // 当前节点位置
let reverseHead = null
let reverseTail = null
while (current) {
if (i >= left && i <= right) {
if (!reverseHead) {
reverseHead = current
reverseTail = current
prev.next = current
current = current.next
} else {
let next = current.next
prev.next = current
current.next = reverseHead
reverseHead = current
current = next
}
i++
continue
}
if (reverseTail) {
reverseTail.next = current
reverseTail = null
} else {
prev.next = current
}
prev = current
current = current.next
i++
}
if (reverseTail) {
reverseTail.next = current
}
return newHead.next
}