leetcode刷刷題(39) ---- 刪除鏈表的倒數第N個節點(C語言版)

2020-3-24

  • Every boring hour in life is unique.
    在生命中,再無聊的時光也是限量版。

題目

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

示例:
給定一個鏈表: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.
說明:
給定的 n 保證是有效的。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

個人解答:(C版本)

  • 方法一:先求出鏈表長度len,然後就得出刪除的節點爲第len-n個節點了。(該方法更容易實現)
  • 方法二:讓兩個指針保持n-1的距離移動,當走在前面的指針到達末尾時,後面的指針指向的位置即爲要刪除的點。
    有一個比較棘手的問題是如果刪除的是頭結點,這時可以考慮增加一個新的頭結點,使原來的頭結點不再特殊。
    本代碼示例採用方法二,詳細的註釋看下面代碼。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeNthFromEnd(struct ListNode* head, int n){

    int interval = 0;
    struct ListNode* q = NULL;
    struct ListNode* p = NULL;
    struct ListNode* t = NULL;
    struct ListNode* headnode = NULL;

    // 增加一下頭指針,爲了更好的應對刪掉給定鏈表的第一個節點
    headnode = (struct ListNode*)malloc(sizeof(struct ListNode));

    // 將該節點作爲新的節點
    headnode->next = head;
    p = t = q = headnode;

    // p與q不斷向後移動,兩者保持n-1的距離,當q到達最後一個節點時,此時的p即爲要刪除的點
    while(1)
    {
        q = q->next;
        interval++;
        if(interval >= n) // 此時p可以開始移動,之後就保持間隔
        {
            t = p;  // t記錄要p的前一個節點,方便刪除p
            p = p->next;
            if(q->next == NULL)
            {
                // 刪除並釋放
                t->next = t->next->next;
                free(p); 
                break;
            }
        }

    }

    // 返回真正的頭結點
    head = headnode->next;

    // 釋放動態分配的內存
    headnode->next=headnode;
    free(headnode);

    return head;
}
  • 複雜度分析
    1)一次循環就能找到結果,所以該算法的時間複雜度爲O(n)。
    2)由於只使用了少量的變量,空間複雜度爲O(1)。
  • 運行結果:
    在這裏插入圖片描述
他山之石:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章