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

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

題目描述:

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

示例:

給定一個連結串列: 1->2->3->4->5, 和 n = 2.

當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.
說明:

給定的 n保證是有效的。

進階:

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

程式碼實現:(暴力解決)

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode *head, int n) {
        ListNode *dummyNode = new
ListNode(0); dummyNode->next = head; ListNode* p = head; int size = 0; while(p != NULL) { p = p-> next; size++; } int ans = 0; // ListNode* flag ; p = dummyNode; while(p != NULL) {
if(ans + n == size ) { ListNode* k = p-> next; p -> next = k -> next ; // p = k; delete(k); } p = p -> next; ans++; } return dummyNode -> next ;
// return head; } };

做題總結:

1:要先引入一個啞結點,這道題中的啞結點就是dummyNode ,是在head之前附加了一個節點,原因是如果要刪除head連結串列中第一個節點若不引入啞結點,還要單獨考慮情況,而有了啞結點便統一了操作。

解法二:(雙指標)

class Solution{
    public:
        ListNode* removeNthFromEnd(ListNode* head,int n)
        {
            ListNode* dummyHead = new ListNode(0);
            dummyHead -> next = head;
            
            ListNode* p = dummyHead;
            ListNode* q = dummyHead;
            for(int i = 0 ; i < n+1 ; i ++)
            {
                q = q-> next;
            }
            while(q){
                p = p-> next;
                q = q-> next;
            }
            
            ListNode* delNode = p->next;
            p->next = delNode->next;
            delete delNode;
            
            return dummyHead->next;
        }
};

啟示:

這種解法是思路上的啟發,運用了啞結點和雙指標p和q,將q移動到距離p 有n 的節點位置上,然後兩指標保持距離一起移動,直到q到NULL位置,而p指向的節點的後一個節點就是要刪除的節點。