1. 程式人生 > >【leetcode】刪除連結串列的倒數第N個節點(C語言解答)

【leetcode】刪除連結串列的倒數第N個節點(C語言解答)

題目:

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

示例:

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

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

說明:

給定的 n 保證是有效的。

進階:

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

解題思路:

開始的時候,我的想法是:先計算連結串列的長度length,然後通過length和n計算出要刪除的結點是第幾個節點!這是一種解法,但在寫程式時,需要考慮多種特殊情況:1.要刪除的節點如果是頭節點怎麼辦?2.要刪除的節點是尾節點怎麼辦?3.要刪除的節點如果既是頭節點也是尾節點怎麼辦?(連結串列中只有一個節點)

在諸多特殊情況的處理過程中,程式碼逐漸變得複雜、繁瑣、不堪入目:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode* p;
    struct ListNode* q;
    int length=0;
    int i,j;

    if(head->next==NULL) return head;
    p=head->next;
    while(p){
        length++;//計算連結串列長度
        p=p->next;
    }
    
    i=length-n;//計算倒數第n個節點是第幾個節點  3
    p=head->next;
    j=0;
    if(i==-1&&length==0)
    {
        head=NULL;
        return head;
    }
    
    if(i==-1)//如果要刪除的是連結串列的第一個節點
    {
        head->next=p->next;
        return head;
    }
    
    while(p->next&&j<i-1)
    {
        p=p->next;//查詢第i-1個節點
        j++;
    }
    
    q=p->next;//q指向第i個節點
    if(n==1)//要刪除的是連結串列的最後一個節點
    {
        p->next=NULL;
    }
    else
    {  
    p->next=q->next;//修改連結關係
    }
    free(q);
    return head;
}

一番折騰之後,我明白了雙指標的用法,改進了解題思路:

首先讓指標first指向頭節點,然後讓其向後移動n步,接著讓指標sec指向頭結點,並和first一起向後移動。當first的next指標為NULL時,sec即指向了要刪除節點的前一個節點,接著讓first指向的next指標指向要刪除節點的下一個節點即可。注意如果要刪除的節點是首節點,那麼first向後移動結束時會為NULL,這樣加一個判斷其是否為NULL的條件,若為NULL則返回頭結點的next指標。

用一張圖解釋就是:

C語言解答:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode* first=head;
    while(n--!=0)
        first=first->next;
    if(!first)
        return head->next;
    struct ListNode* sec=head;
    while(first->next!=NULL){
        sec=sec->next;
        first=first->next;
    }
    sec->next=sec->next->next;
    return head;
    
}