No.092 反转链表2
题目:
给你单链表的头指针 head 和两个整数 left, right,其中 left <= right。请你反转从位置 left 到 位置 right 的链表节点,返回反转后的链表。
分析:
使用一趟扫描,在扫描过程中:
先找到 left 及其前驱节点 leftpre,并保存
同时将 left 节点保存为 lefttail,继续遍历,并反转 [left, right] 中的节点
找到 right 节点之后,更新 left, right 节点的Next值
确定新的 head
// date 2023/10/11
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseBetween(head *ListNode, left int, right int) *ListNode {
// leftpre, left, right, rightpost
// leftpre.Next = right
// left.Next = rightpost
if head == nil || head.Next == nil {
return head
}
// 区间内没有节点,不需要反转
if left == right {
return head
}
var leftPre, tail, cur *ListNode
cur = head
for left > 1 {
leftPre = cur
cur = cur.Next
left--
right--
}
// now cur is the left node
// save it
l := cur
for right > 1 {
after := cur.Next
cur.Next = tail
tail = cur
cur = after
right--
}
// now cur is the right node
l.Next = cur.Next
cur.Next = tail
// when left > 1, the head is newHead
if leftPre != nil {
leftPre.Next = cur
return head
}
// when left = 1, the right is new head
return cur
}

解法2:实现区间节点反转函数。
// date 2024/03/14
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseBetween(head *ListNode, left int, right int) *ListNode {
if left == right {
return head
}
cur := head
leftPre := head
for left > 1 {
leftPre = cur
cur = cur.Next
left--
right--
}
// now cur is the left
leftNode := cur
for right > 1 {
cur = cur.Next
right--
}
// now cur is the right
rightPost := cur.Next
if leftNode == head {
return reverse(leftNode, rightPost)
}
leftPre.Next = reverse(leftNode, rightNode)
return head
}
// [first, last)
func reverse(first, last *ListNode) *ListNode {
prev := last
for first != last {
temp := first.Next
first.Next = prev
prev = first
first = temp
}
return prev
}
最后更新于