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

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

題目:

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

示例:

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

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

給定的 n保證是有效的。

進階:

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

解答:

自己的解答:

ListNode* removeNthFromEnd(ListNode* head, int n) 
{
    if (n <= 0)
        return head;

    ListNode* tmp = head;
    
int num = 0; while (tmp != nullptr) { num++; tmp = tmp->next; } if (n == num) return head->next; ListNode* headTmp = head; ListNode* pre; int deleteK = num - n; int idx = 0; while (idx < deleteK) { pre = headTmp; headTmp
= headTmp->next; idx++; } pre->next = headTmp->next; delete headTmp; return head; }

答案裡用雙指標:

  由於我們需要找到倒數第 n 個節點,因此我們可以使用兩個指標 first 和 second 同時對連結串列進行遍歷,並且first 比second 超前 n 個節點。當first 遍歷到連結串列的末尾時,second 就恰好處於倒數第 n 個節點。

  具體地,初始時first 和 second 均指向頭節點。我們首先使用first 對連結串列進行遍歷,遍歷的次數為 n。此時,first 和 second 之間間隔了 n−1 個節點,即first 比second 超前了n 個節點。

  在這之後,我們同時使用first 和 second 對連結串列進行遍歷。當 first 遍歷到連結串列的末尾(即 first 為空指標)時,second 恰好指向倒數第 n 個節點。

根據該思路編寫程式碼如下:

ListNode* removeNthFromEnd2(ListNode* head, int n)
{
    if (n == 0)
        return head;

    ListNode* tmp = head;
    int num = 0;
    while (tmp != nullptr)
    {
        num++;
        tmp = tmp->next;
    }

    if (n == num)
        return head->next;

    ListNode* first = head;
    ListNode* second = head;

    int idx = 0;
    while (idx < n)
    {
        first = first->next;
        idx++;
    }

    while (first->next != nullptr)
    {
        first = first->next;
        second = second->next;
    }

    first = second;
    second = second->next;
    first->next = second->next;
    delete second;

    return head;
}

  看了題解的答案,並沒有統計連結串列元素的個數,解答的程式碼如下:

示意圖如下圖所示:

圖片來源:

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/