反转链表系列题总结
206. 反转链表
—— 最基本的反转链表
迭代
func reverseList(head *ListNode) *ListNode {
//迭代
var prev *ListNode
cur := head
for cur != nil {
next := cur.Next
cur.Next = prev
prev = cur
cur = next
}
return prev
}
递归
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
newHead := reverseList(head.Next)
head.Next.Next = head
head.Next = nil
return newHead
}
反转链表前k个节点
迭代
func reverseK(head *ListNode, k int) *ListNode {//反转链表前k个节点
if k <= 1 {
return head
}
var prev *ListNode
cur := head
for i := 0; i < k && cur != nil; i++ {
next := cur.Next
cur.Next = prev
prev = cur
cur = next
}
head.Next = cur
return prev
}
递归
var successor *ListNode //递归法reverseK需要用到的变量,记录第k+1个节点
func reverseK(head *ListNode, k int) *ListNode {//反转链表前k个节点
if k == 0 {
return head
}
if k == 1 {//给第k+1个节点successor赋值
successor = head.Next
return head
}
newHead := reverseK(head.Next, k - 1);
head.Next.Next = head
head.Next = successor
return newHead
}
92. 反转链表 II
—— 反转链表从left~right的部分
用到 反转链表前k个节点 作为子函数
迭代
若left==1,则直接返回reverseK(head, right - left + 1)
若left!=1,cur移动到第left个节点(prev指向第left-1个节点),perv.Next = reverseK(cur, right - left + 1),最后返回head
func reverseBetween(head *ListNode, left int, right int) *ListNode {
if left == 1 {
return reverseK(head, right - left + 1)
}
cur := head
var prev *ListNode = nil
for i := 1; i < left && cur != nil; i++ {
prev = cur
cur = cur.Next
}
if cur == nil {
return head
}
prev.Next = reverseK(cur, right - left + 1)
return head
}
递归
若left==1,则直接返回reverseK(head, right - left + 1)
若left!=1,head.Next = reverseBetween(head.Next, left - 1, right - 1), 最后return head
func reverseBetween(head *ListNode, left int, right int) *ListNode {
if left == 1 {
return reverseK(head, right - left + 1)
}
head.Next = reverseBetween(head.Next, left - 1, right - 1)
return head
}
25. K 个一组翻转链表
仍然用到 反转链表前k个节点 作为子函数
迭代
func reverseKGroup(head *ListNode, k int) *ListNode {
//首先要判断是否有>=k个节点,否则直接返回原来的head不做任何操作
if head == nil {
return head
}
cur := head
for i := 1; cur != nil && i < k; i++ {
cur = cur.Next
}
if cur == nil {//没有k个节点了,不反转了直接返回原来的head
return head
}
//确定有>=k个节点后,开始迭代调用。(此时cur指向第k个节点)
cur.Next = reverseKGroup(cur.Next, k) //迭代 k个一组反转第k+1个节点开头的链表
newHead := reverseK(head, k) //反转前k个
return newHead
}