1. 程式人生 > 實用技巧 >203. 移除連結串列元素(C++)

203. 移除連結串列元素(C++)

目錄

題目

刪除連結串列中等於給定值 val 的所有節點。

示例:

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

分析與題解

區分頭結點

直接使用給定的頭結點進行節點的刪除。此時需要對頭結點跟其他節點的刪除進行分類討論。

對於首節點的情況,我們先儲存首節點的位置,再向後移動頭指標,最後釋放刪除節點的空間

while (head != NULL && head->val == val) { // 注意這裡不是if
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
        }

當退出迴圈時,可以確定的是首節點對應的值肯定不為目標值,我們再對非首節點的目標節點進行刪除:

		ListNode* cur = head;
        while (cur != NULL && cur->next!= NULL) {
            if (cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
                cur = cur->next;
            }
        }

為了避免影響頭指標的位置,我們使用額外指標對連結串列剩餘節點進行遍歷。每次需要對當前結點和下一個結點是否為空進行討論。

完整程式碼如下:

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 先考慮頭結點為目標值的情況
        while (head != nullptr && head->val == val) {
            // 先獲取待刪除元素 方便進行空間釋放
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
        }

        // 退出上述迴圈說明首位元素值不為目標節點
        // 使用另一個變數進行內部節點刪除的迴圈
        // 保持頭結點位置正確性 方便進行返回
        ListNode* cur = head;
        while (cur != nullptr && cur->next != nullptr) {
            if (cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }
            else if (cur->next->val != val)
                cur = cur->next;
        }
        return head;
    }
};

統一刪除節點程式碼(增加虛節點)

不直接使用題目給定的頭節點指標,在之前先新增一個虛節點,以此保證刪除節點程式碼風格的統一。

ListNode* dummyNode =new ListNode(0);
dummyNode->next = head;

另外需要注意,在定義連結串列結構體的時候,我們採用建構函式初始值列表來進行初始化,冒號後以成員變數名(成員初始值)的形式進行初始化。

花括號內為空函式的原因是該列表的唯一目的是為資料成員賦初值,一旦沒有其他任務需要執行,函式體也就為空了。

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

最後所有元素按照連結串列內的節點刪除來進行處理,完整程式碼如下:

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 先考慮頭結點為目標值的情況
        while (head != nullptr && head->val == val) {
            // 先獲取待刪除元素 方便進行空間釋放
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
        }

        // 退出上述迴圈說明首位元素值不為目標節點
        // 使用另一個變數進行內部節點刪除的迴圈
        // 保持頭結點位置正確性 方便進行返回
        ListNode* cur = head;
        while (cur != nullptr && cur->next != nullptr) {
            if (cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }
            else if (cur->next->val != val)
                cur = cur->next;
        }
        return head;
    }
};