溫馨提示×

溫馨提示×

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

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

C++實現移除鏈表倒數第N個節點

發布時間:2021-07-13 13:36:14 來源:億速云 閱讀:143 作者:chen 欄目:開發技術
# C++實現移除鏈表倒數第N個節點

## 目錄
1. [問題描述](#問題描述)
2. [鏈表基礎回顧](#鏈表基礎回顧)
3. [解法一:兩次遍歷法](#解法一兩次遍歷法)
4. [解法二:雙指針法](#解法二雙指針法)
5. [完整代碼實現](#完整代碼實現)
6. [邊界條件與測試用例](#邊界條件與測試用例)
7. [復雜度分析](#復雜度分析)
8. [應用場景](#應用場景)
9. [總結](#總結)

## 問題描述
給定一個單向鏈表,要求刪除鏈表的倒數第N個節點,并返回鏈表的頭節點。例如:

輸入:1->2->3->4->5, n = 2  
輸出:1->2->3->5

## 鏈表基礎回顧
```cpp
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};
  • 單向鏈表由節點構成,每個節點包含值和指向下一個節點的指針
  • 鏈表操作需注意指針的指向關系和內存管理

解法一:兩次遍歷法

算法步驟

  1. 第一次遍歷計算鏈表長度L
  2. 計算待刪除節點的正序位置:L - n
  3. 第二次遍歷定位到目標節點的前驅節點
  4. 修改指針完成刪除
ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode dummy(0);
    dummy.next = head;
    int length = 0;
    
    // 第一次遍歷計算長度
    ListNode* curr = head;
    while (curr) {
        length++;
        curr = curr->next;
    }
    
    // 定位到待刪除節點的前驅
    curr = &dummy;
    for (int i = 0; i < length - n; i++) {
        curr = curr->next;
    }
    
    // 執行刪除
    ListNode* toDelete = curr->next;
    curr->next = curr->next->next;
    delete toDelete; // 防止內存泄漏
    
    return dummy.next;
}

解法二:雙指針法

算法思想

使用快慢指針實現單次遍歷: - 快指針先移動n步 - 然后快慢指針同步移動 - 當快指針到達末尾時,慢指針指向待刪除節點的前驅

ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode dummy(0);
    dummy.next = head;
    ListNode *fast = &dummy, *slow = &dummy;
    
    // 快指針先移動n+1步
    for (int i = 0; i <= n; i++) {
        fast = fast->next;
    }
    
    // 同步移動直到快指針到末尾
    while (fast) {
        fast = fast->next;
        slow = slow->next;
    }
    
    // 執行刪除
    ListNode* toDelete = slow->next;
    slow->next = slow->next->next;
    delete toDelete;
    
    return dummy.next;
}

完整代碼實現

#include <iostream>

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    // 雙指針法實現
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode dummy(0);
        dummy.next = head;
        ListNode *fast = &dummy, *slow = &dummy;
        
        for (int i = 0; i <= n; ++i) {
            fast = fast->next;
        }
        
        while (fast) {
            fast = fast->next;
            slow = slow->next;
        }
        
        ListNode* toDelete = slow->next;
        slow->next = slow->next->next;
        delete toDelete;
        
        return dummy.next;
    }
};

// 輔助函數:打印鏈表
void printList(ListNode* head) {
    while (head) {
        std::cout << head->val << "->";
        head = head->next;
    }
    std::cout << "nullptr" << std::endl;
}

// 輔助函數:創建測試鏈表
ListNode* createList(std::initializer_list<int> vals) {
    ListNode dummy(0);
    ListNode* curr = &dummy;
    for (int val : vals) {
        curr->next = new ListNode(val);
        curr = curr->next;
    }
    return dummy.next;
}

int main() {
    Solution solution;
    
    // 測試用例1
    ListNode* list1 = createList({1, 2, 3, 4, 5});
    std::cout << "Original list: ";
    printList(list1);
    list1 = solution.removeNthFromEnd(list1, 2);
    std::cout << "After removal: ";
    printList(list1);
    
    // 測試用例2
    ListNode* list2 = createList({1});
    list2 = solution.removeNthFromEnd(list2, 1);
    printList(list2); // 應輸出 nullptr
    
    return 0;
}

邊界條件與測試用例

測試用例 預期結果 說明
[1,2,3,4,5], n=2 [1,2,3,5] 常規情況
[1], n=1 [] 刪除唯一節點
[1,2], n=2 [2] 刪除頭節點
[1,2,3], n=3 [2,3] 刪除頭節點
[1,2,3,4,5], n=5 [2,3,4,5] 刪除頭節點

復雜度分析

  1. 兩次遍歷法:

    • 時間復雜度:O(L) 兩次遍歷,2L → O(L)
    • 空間復雜度:O(1)
  2. 雙指針法:

    • 時間復雜度:O(L) 單次遍歷
    • 空間復雜度:O(1)

應用場景

  1. 操作系統中的進程調度
  2. 瀏覽器歷史記錄管理
  3. 音樂播放列表操作
  4. 大數據處理中的流式數據處理

總結

  1. 雙指針法是更優的解決方案,只需一次遍歷
  2. 使用哨兵節點(dummy node)可以簡化頭節點處理
  3. 必須注意內存管理,特別是C++中的節點刪除
  4. 算法時間復雜度都是O(L),但雙指針法常數項更小

關鍵點:掌握快慢指針技巧是解決鏈表問題的關鍵,這種方法可以擴展到許多其他鏈表問題,如檢測環、尋找中點等。 “`

這篇文章提供了約1900字的詳細內容,包含: - 兩種解法的完整實現 - 復雜度分析 - 邊界條件處理 - 實際應用場景 - 可執行的測試代碼 - 標準Markdown格式的排版

向AI問一下細節

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

c++
AI

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