Leetcode(19)刪除連結串列的倒數第N個節點
阿新 • • 發佈:2018-12-11
題目描述
給定一個連結串列,刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。
示例:
給定一個連結串列: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.
說明:
給定的 n 保證是有效的。
進階:
你能嘗試使用一趟掃描實現嗎?
解題思路
方法一、遍歷兩次連結串列
刪除倒數n的節點,首先需要知道整個連結串列的長度N,就可以轉化為刪除連結串列第N-n+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) { ListNode *dummy=new ListNode(0); dummy->next=head; int length=0; ListNode *first=head; while(first!=NULL) { length++; first=first->next; } length-=n; first=dummy; while(length>0) { length--; first=first->next; } first->next=first->next->next; return dummy->next; } };
方法二、一次便利連結串列
上述演算法可以優化為只使用一次遍歷。我們可以使用兩個指標而不是一個指標。第一個指標從列表的開頭向前移動 n+1 步,而第二個指標將從列表的開頭出發。現在,這兩個指標被 n 個結點分開。我們通過同時移動兩個指標向前來保持這個恆定的間隔,直到第一個指標到達最後一個結點。此時第二個指標將指向從最後一個結點數起的第 n 個結點。我們重新連結第二個指標所引用的結點的 next 指標指向該結點的下下個結點。
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode *dummy=new ListNode(0); dummy->next=head; ListNode *first=dummy; ListNode *second=dummy; for(int i=1;i<=n+1;i++) { first=first->next; } while(first!=NULL) { first=first->next; second=second->next; } second->next=second->next->next; return dummy->next; } };