LeetCode 19——刪除連結串列的倒數第 N 個節點
阿新 • • 發佈:2018-11-08
1. 題目
給定一個連結串列,刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。
示例:
給定一個連結串列: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.
說明:
給定的 n 保證是有效的。
進階:
你能嘗試使用一趟掃描實現嗎?
2. 思路
定義兩個指標 p1、p2,剛開始兩個指標都指向頭結點。如果要刪除倒數第 N 個結點,我們就讓 p2 先前進 N-1 步,這時候 p2 後面的節點個數為 K,那我們要刪除的結點也就是位於 p1 後面的第 K 個結點
如下圖所示,假設我們要刪除倒數第 3 個結點,p2 前進 2 步後指向第三個結點。
- p2 後面還有 1 個結點,而我們要刪除的結點也就是位於 p1 後面的第 1 個結點——結點 2。
- 一種特殊情況是要刪除倒數第 4 個結點,也就是第 1 個結點。這時候,我們只需要讓 head 指向第 2 個結點即可。
其他情況下,在 p2 指標到達指定位置後。我們先讓 p2 指標後移一個位置,然後再同時讓 p1 和 p2 向後移動。當 p2 指向最後一個結點時,p1 就指向了待刪除節點的前一個結點,此時讓 p1 指向 p1 後面的第 2 個結點即可刪除指定的結點。
以下為刪除倒數第 1 個結點的過程。
- 當然,不要忘了釋放刪除結點的記憶體。
- 程式碼如下
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { if (head == NULL) { return head; } else { int i = 1; ListNode *p1 = head, *p2 = head, *temp = NULL; while (i != n) // p2 指標前進 n-1 步 { i++; p2 = p2->next; } if (p2->next == NULL) // 刪除第一個結點的情況 { temp = head; head = head->next; // head 指向第 2 個結點 } else { p2 = p2->next; // p2 指標先前進 1 步 while(p2->next) // p1、p2 指標同步向後移動 { p2 = p2->next; p1 = p1->next; } temp = p1->next; p1->next = p1->next->next; // p1 指向其後面的第 2 個結點 } delete(temp); // 釋放結點記憶體 } return head; } };
獲取更多精彩,請關注「seniusen」!