leetcode19_刪除鏈表的倒數第N個節點_鏈表_雙指針_遞歸

1. 最簡單的想法就是先求出鏈表的長度len,再找到(len-k)個節點,即刪除節點的前一個節點,就可以將其刪除.

2. 兩次遍歷.

/**
 * 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;
        ListNode* tmp = head;
        int count = 0;
        //求鏈表長度.注意
        //不要用head求,會改變head,另外指定tmp.
        while(tmp!=NULL) {
            tmp = tmp->next;
            count++;
        }
        //啞結點消除刪除只剩一個節點情況,以及刪除第一個節點的情況
        //的邊界條件.
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        tmp = dummy;
        int c = 0;
        while(c!=count-n) {
            tmp = tmp->next;
            c++;
        }
        //找到了就停止.
        tmp->next = tmp->next->next;
        //返回啞結點的後一個節點.
        return dummy->next;
    } 
};

3. 一次遍歷

4. 可以優化爲只使用一次遍歷.使用雙指針.快慢指針,快指針先走n-2,然後快慢指針一起走,這樣快慢指針的間隔保持恆定的間隔,即可以求得其倒數第n個節點前一個節點,便可以將倒數第n個節點刪除了.

5. 快慢指針找到倒數第N個節點.

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head==NULL) return head;
        ListNode* dummy = new ListNode(0);
        //啞結點消除邊界情況,比如只剩一個數,
        //或者刪除第一個節點.
        dummy->next = head;
        ListNode* slow = dummy;
        ListNode* fast = dummy;
        //使快慢指針的間隔爲n.
        for(int i=1;i<=n;i++) {
            fast = fast->next;
        }
        //這樣當快指針走到末尾時,慢指針
        //就是倒數第N個節點.
        while(fast->next!=NULL) {
            slow = slow->next;
            fast = fast->next;
        }
        slow->next = slow->next->next;
        return dummy->next;

    } 
};

三. 遞歸方法

1. 遞歸方法分爲遞和歸兩個過程.

2. 遞歸不好理解的時候可以具體舉幾個簡單的例子, 比如[1],1即一個數的情況.

class Solution {
public:
    int i=0;
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        //先是遞的過程,如果找到最後一個節點,直接返回NULL;
        if(head==NULL) return NULL;
        //當前指針下一個指針是哪個.
        head->next = removeNthFromEnd(head->next,n);
        //歸的時候統計當前是第幾個指針.
        i++;
        //如果是待刪除指針,返回當前指針下一個
        //否則返回head.
        if(i==n) return head->next;
        else return head;
    } 
};

發佈了95 篇原創文章 · 獲贊 26 · 訪問量 2128
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章