19.Remove Nth Node From End of List

大三準備面試,開始做leetCode,遇到有意思的題在這裏做個總結。

這是一道easy題,但我已經很久沒用過鏈表所以還是做個總結。

做leetCode的題雖然不用自己寫main函數,但我還是習慣自己寫一個main函數去做測試。在寫main函數的過程中發現自己已經不會建表…
弄了半天總算把建表的邏輯弄明白,建表邏輯如下:

    #define NUM 1

    struct ListNode {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL) {}
    };

    int main(){
        ListNode *root,*node;
        root = new ListNode(-1);
        root->next = NULL;
        node = root;
        for(int i = 0; i< NUM;i++){
            ListNode *now = new ListNode(i);
            node->next = now;
            node = now;
        }
        node -> next = NULL; 
    }

一開始有根節點和一個普通節點,讓根節點和普通節點爲統一節點以便後面的循環。這時候鏈表只有一個節點——根節點。然後在循環中建立一個新的節點,讓原有鏈表的末端指向新的節點,再把鏈表的末端擴展到包含新節點的位置。

遍歷鏈表:

node = root;
while(node != NULL){
    cout<<node->val<<endl;
    node = node->next;
}

節點不爲空就繼續往下,直到爲空

現在我們再來看原問題,問題要求我們去除鏈表的倒數第n個節點。我這裏使用的方法是用兩個指針一前一後去做遍歷,前面的指針要比後面的指針快n個位置,這樣當前面的指針到尾的時候,後面那個指針就讓當前節點的下一節點爲下下節點就可以了。

ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode *node,*node2;
    node = node2 = head;
    int temp = 0;
    while(node->next!= NULL){
        node = node->next;
        if(temp >= n){
            node2 = node2->next;
        }
        temp++;
    }
    if(temp+1==n && node2->next != NULL)
        return node2->next;
    if(node2->next == NULL){
        return NULL;
    }else if (node2->next->next == NULL && node2->next != NULL){
        node2->next = NULL;
    }else if(node2->next != NULL && node2->next->next != NULL){
        node2->next = node2->next->next;
    }
    return head;
}

首先我們要注意到:

if(node2->next == NULL){
        return NULL;
    }else if (node2->next->next == NULL && node2->next != NULL){
        node2->next = NULL;
    }else if(node2->next != NULL && node2->next->next != NULL){
        node2->next = node2->next->next;
    }

在每次使用指針的時候,我們都要注意越界的問題,必須先要進行判斷該指針是否爲空,如若不然很容易造成運行出錯。比如說鏈表爲1,且我要去除倒數第一個節點時,如果不判斷node2->next是否爲空,那麼勢必會因爲1後面是空而造成運行出錯。

同時還有當鏈表的長度和n是一樣的時候的特殊處理:

if(temp+1==n && node2->next != NULL)
        return node2->next;

因爲前面的邏輯只能去掉node2之後的節點或者直接返回空,如果遇到1->2,n=2時就會答案錯誤。

以上代碼是我通過leetCode的代碼,但在寫這篇博客的時候,我突然意識到還是有問題,如果傳進來的根節點就是空的,那我的代碼還是會運行出錯,所以應該再加一個根節點是否爲空的判斷。

總之遇到指針的問題必須要時時刻刻注意指針越界的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章