題目描述
給出一個連結串列,每 k 個節點一組進行翻轉,並返回翻轉後的連結串列。
k 是一個正整數,它的值小於或等於連結串列的長度。如果節點總數不是 k 的整數倍,那麼將最後剩餘節點保持原有順序。
示例:
給定這個連結串列:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明:
- 你的演算法只能使用常數的額外空間。
- 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
解題思路
1. 取連結串列的前K個節點,如果夠K個節點,就截斷後進行反轉,不夠K個節點,說明處理完了,return
2. 反轉完前K個節點後,使用遞迴,處理後面的連結串列
程式碼實現
// ListNode Definition for singly-linked list.
type ListNode struct {
Val int
Next *ListNode
}
func reverseKGroup(head *ListNode, k int) *ListNode {
if k < 2 || head == nil || head.Next == nil {
return head
}
tail, needReverse := getTail(head, k)
if needReverse {
tailNext := tail.Next
//斬斷 tail 後的連結
tail.Next = nil
head, tail = reverse(head, tail)
//tail 後面接上尾部的遞迴處理
tail.Next = reverseKGroup(tailNext, k)
}
return head
}
func getTail(head *ListNode, k int) (*ListNode, bool) {
for k > 1 && head != nil {
head = head.Next
k--
}
return head, k == 1 && head != nil
}
func reverse(head, tail *ListNode) (*ListNode, *ListNode) {
//反轉連結串列
prev, cur := head, head.Next
for cur != nil {
prev, cur, cur.Next = cur, cur.Next, prev
}
return tail, head
}
GitHub
- 原始碼傳送門
- 專案中會提供各種資料結構及演算法的Golang實現, LeetCode解題思路及答案