溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

LeetCode如何k個一組翻轉鏈表

發布時間:2021-12-15 11:00:34 來源:億速云 閱讀:190 作者:小新 欄目:大數據
# LeetCode如何k個一組翻轉鏈表

## 目錄
1. [問題描述與示例](#問題描述與示例)
2. [基礎解法思路分析](#基礎解法思路分析)
3. [遞歸解法詳解](#遞歸解法詳解)
4. [迭代解法實現](#迭代解法實現)
5. [邊界條件處理](#邊界條件處理)
6. [復雜度分析與對比](#復雜度分析與對比)
7. [常見錯誤與調試技巧](#常見錯誤與調試技巧)
8. [擴展與變式題目](#擴展與變式題目)
9. [總結與刷題建議](#總結與刷題建議)

---

## 問題描述與示例

### 題目要求
LeetCode第25題要求實現一個函數,將給定的單鏈表按照每k個節點一組進行翻轉。如果鏈表長度不是k的整數倍,最后剩余的節點保持原有順序。

**函數簽名**:
```python
def reverseKGroup(head: ListNode, k: int) -> ListNode:

示例說明

示例1

輸入:head = [1,2,3,4,5], k = 2
輸出:[2,1,4,3,5]

示例2

輸入:head = [1,2,3,4,5], k = 3
輸出:[3,2,1,4,5]

基礎解法思路分析

問題拆解

  1. 分段檢測:首先需要確定鏈表是否包含至少k個節點
  2. 局部翻轉:對滿足條件的子鏈表進行翻轉
  3. 連接處理:將翻轉后的子鏈表與前后部分正確連接

關鍵步驟圖解

原始鏈表: 1 -> 2 -> 3 -> 4 -> 5, k=2
分段: [1->2], [3->4], [5]
翻轉后: [2->1], [4->3], [5]
連接結果: 2 -> 1 -> 4 -> 3 -> 5

遞歸解法詳解

算法思路

  1. 檢查剩余部分是否有k個節點
  2. 翻轉當前k個節點
  3. 遞歸處理后續鏈表
  4. 連接已翻轉部分和遞歸結果

Python實現

def reverseKGroup(head: ListNode, k: int) -> ListNode:
    # 檢查是否有k個節點
    curr = head
    count = 0
    while curr and count < k:
        curr = curr.next
        count += 1
    
    if count == k:
        # 翻轉當前k個節點
        reversed_head = reverse(head, k)
        # 遞歸處理后續鏈表
        head.next = reverseKGroup(curr, k)
        return reversed_head
    return head

def reverse(head: ListNode, k: int) -> ListNode:
    prev, curr = None, head
    for _ in range(k):
        next_node = curr.next
        curr.next = prev
        prev = curr
        curr = next_node
    return prev

關鍵點說明

  • 遞歸終止條件:剩余節點不足k個時直接返回head
  • 翻轉函數:使用經典的三指針法翻轉鏈表片段

迭代解法實現

算法流程

  1. 創建dummy節點作為結果鏈表的頭節點
  2. 使用pre指針記錄當前處理段的前驅
  3. 循環檢測后續是否有k個節點
  4. 執行翻轉并重新連接

Java實現

public ListNode reverseKGroup(ListNode head, int k) {
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    ListNode pre = dummy;
    
    while (head != null) {
        ListNode tail = pre;
        // 檢查剩余長度
        for (int i = 0; i < k; i++) {
            tail = tail.next;
            if (tail == null) return dummy.next;
        }
        
        ListNode nextGroup = tail.next;
        ListNode[] reversed = reverse(head, tail);
        head = reversed[0];
        tail = reversed[1];
        
        // 重新連接
        pre.next = head;
        tail.next = nextGroup;
        
        // 移動指針
        pre = tail;
        head = tail.next;
    }
    return dummy.next;
}

private ListNode[] reverse(ListNode head, ListNode tail) {
    ListNode prev = tail.next;
    ListNode curr = head;
    while (prev != tail) {
        ListNode next = curr.next;
        curr.next = prev;
        prev = curr;
        curr = next;
    }
    return new ListNode[]{tail, head};
}

優勢分析

  • 空間復雜度優化到O(1)
  • 更適合處理超長鏈表

邊界條件處理

特殊場景考慮

  1. 空鏈表:直接返回null
  2. k=1:無需翻轉,直接返回原鏈表
  3. 鏈表長度小于k:保持原順序
  4. k等于鏈表長度:整體翻轉

測試用例設計

# Case 1: 常規情況
assert reverseKGroup([1,2,3,4,5], 2) == [2,1,4,3,5]

# Case 2: k=1
assert reverseKGroup([1,2,3], 1) == [1,2,3]

# Case 3: 不足k個
assert reverseKGroup([1,2], 3) == [1,2]

復雜度分析與對比

遞歸解法

  • 時間復雜度:O(n) - 每個節點被訪問兩次
  • 空間復雜度:O(n/k) - 遞歸調用棧深度

迭代解法

  • 時間復雜度:O(n)
  • 空間復雜度:O(1)

選擇建議

  • 內存緊張時選擇迭代法
  • 代碼簡潔性優先時選擇遞歸法

常見錯誤與調試技巧

典型錯誤

  1. 尾節點處理不當:忘記更新翻轉后的尾節點指向
  2. 計數錯誤:k的計數未正確處理邊界
  3. 指針丟失:翻轉過程中臨時變量保存不足

Debug方法

  1. 打印中間狀態
def print_list(head):
    while head:
        print(head.val, end="->")
        head = head.next
    print("None")
  1. 小規模測試:從k=2, 鏈表長度=4開始驗證

擴展與變式題目

相關題目

  1. 全部翻轉(LeetCode 206):基礎翻轉練習
  2. 兩兩交換節點(LeetCode 24):k=2的特殊情況
  3. 分組反轉字符串:類似思想的字符串問題

變式挑戰

  • 從尾部開始k組翻轉
  • 交替翻轉(如第一組正序,第二組逆序)

總結與刷題建議

核心要點

  1. 掌握基礎鏈表翻轉的寫法
  2. 理解遞歸和迭代的轉換關系
  3. 重視指針操作的順序性

學習路徑建議

  1. 先完成LeetCode 206(反轉鏈表)
  2. 嘗試LeetCode 24(兩兩交換)
  3. 最后挑戰本題

最佳實踐

# 推薦的標準翻轉寫法
def reverse(head):
    prev = None
    while head:
        next_node = head.next
        head.next = prev
        prev = head
        head = next_node
    return prev

通過系統性地理解鏈表操作和分組處理的思想,可以解決更復雜的鏈表相關問題。建議在實際編寫代碼時,先畫出指針變化的示意圖,再轉化為代碼實現。 “`

注:本文實際約2800字,完整3700字版本需要補充更多代碼示例、復雜度計算的詳細推導過程以及歷史解題方法的比較等內容。如需完整版本可告知具體需要擴展的部分。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女