1. 程式人生 > 實用技巧 >leetcode hot 100-19. 刪除連結串列的倒數第N個節點

leetcode hot 100-19. 刪除連結串列的倒數第N個節點

19. 刪除連結串列的倒數第N個節點

給定一個連結串列,刪除連結串列的倒數第n個節點,並且返回連結串列的頭結點。

示例:

給定一個連結串列: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.

說明:

給定的 n 保證是有效的。

進階:

你能嘗試使用一趟掃描實現嗎?

思路:

快慢指標,慢指標先走n步,隨後慢指標和快指標同時往後遍歷,遍歷到快指標為空時慢指標所指元素即使倒數第 n 個結點。

劍指offer 14. 連結串列中倒數第 k 個結點的要求與本題幾乎一模一樣,但是這題是要刪除倒數第 n 個結點,而不是直接返回倒數 第 n個結點,所以慢指標移動同時必須記錄下倒數第n個結點的前一個結點。

最後還需要特殊處理如果待刪除的結點是頭結點的情況,即當 pre 指標是null 時,說明待刪除的結點是頭結點,直接返回 head.next

 1 class Solution {
 2     public ListNode removeNthFromEnd(ListNode head, int n) {
 3 
 4         ListNode fast = head, slow = head;
 5         for(int i = 0; i < n; i++){
 6             if(fast == null){
 7                 return
null; 8 } 9 fast = fast.next; 10 } 11 ListNode pre = null; 12 while(fast != null){ 13 fast = fast.next; 14 pre = slow; // 記錄slow前一個結點 15 slow = slow.next; 16 } 17 if(pre == null){ // 如果pre為空,說明待刪除的是第一個結點
18 return head.next; 19 } 20 pre.next = slow.next; // 否則刪除slow這個結點 21 return head; 22 } 23 }
leetcode 執行用時:0 ms > 100.00%, 記憶體消耗:36.8 MB > 56.55%

複雜度分析:

時間複雜度:O(n)。快指標完整的遍歷了一次連結串列,所以時間複雜度為O(n)。 空間複雜度:O(1)。

思路二:藉助輔助頭結點

思路參考:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/

藉助輔助頭結點來代替刪除的是第一個結點時的特別處理,因為需要刪除倒數第 n 個結點,所以需要記錄倒數第 n 個結點的前一個結點,即倒數第 n + 1個結點。所以讓快指標先走 n + 1步,這樣當快指標為空時,慢指標所指結點就是倒數第 n + 1個結點。

前面之所以slow指標不記錄倒數第 n 個結點,而是記錄倒數第 n 結點,是因為擔心連結串列長度剛好是 n, slow指標不好賦初值,如果初值為 null, 那就沒辦法和 fast 一起向下遍歷,如果初值為 head, 但是又擔心連結串列剛好為(n + 1)的情況,這時如果使用 slow == head來判斷待刪除的結點是第一個結點就有問題。

 1 class Solution {
 2     public ListNode removeNthFromEnd(ListNode head, int n) {
 3         ListNode dummyHead = new ListNode();
 4         dummyHead.next = head;
 5         ListNode fast = dummyHead, slow = dummyHead;
 6         for(int i = 0; i < n + 1; i++){ // 快指標先走 n + 1步
 7             if(fast == null){
 8                 return null;
 9             }
10             fast = fast.next;
11         }
12         while(fast != null){
13             fast = fast.next;
14             slow = slow.next;
15         }
16         slow.next = slow.next.next;   // 否則刪除slow這個結點
17         return dummyHead.next;
18     }
19 }
leetcode 執行用時:0 ms > 100.00%, 記憶體消耗:36.1 MB > 91.46%, 空間消耗略小於思路一

複雜度分析:

時間複雜度:O(n)。快指標完整的遍歷了一次連結串列,所以時間複雜度為O(n)。 空間複雜度:O(1)。