链表内指定区间反转
链表内指定区间反转
https://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c
package main
import . "nc_tools"
// import "fmt"
/*
* type ListNode struct{
* Val int
* Next *ListNode
* }
*/
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
func reverseBetween(head *ListNode, m int, n int) *ListNode {
if m == n {
return head
}
if head.Next == nil {
return head
}
pBeforeM := head
for i := 1; i < m-1; i++ {
pBeforeM = pBeforeM.Next
}
pM := pBeforeM.Next
if m == 1 {
pM = head
pBeforeM = nil
}
pN := pM
for i := m; i < n; i++ {
pN = pN.Next
}
pAfterN := pN.Next
pA := pM
pB := pA.Next
for pB != pAfterN {
pTmp := pB.Next
pB.Next = pA
pA = pB
pB = pTmp
}
if pBeforeM != nil {
pBeforeM.Next = pN
}
pM.Next = pAfterN
if m == 1 {
return pA
}
return head
}
解题思路:
- 找出四个节点:
- pM,m 对应的节点
- pBeforeM,pM 的上一个节点
- pN,n 对应的节点
- pAfterN,pN 的下一个节点
- 将 [pM, pN] 之间的节点按照 反转链表 进行处理
- 将 pBeforeM.Next 改为指向 pN,将 pM.Next 改为指向 pAfterN
注意事项:
- m 等于 1 的情况下,需要将 pBeforeM 修正为 nil,将 pM 修正为等于 head
- pBeforeM 不等于 nil 的情况下,才需要执行解题思路中步骤 3 的 "pBeforeM.Next = pN"
- 关于返回值
- m == 1 的情况下,返回 [pM, pN] 区间之间反转后的链表头部
- m != 1 的情况下,直接返回 head