1. 程式人生 > 其它 >2021-01-14

2021-01-14

技術標籤:LeetCode

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

題目描述

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

示例:

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

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

說明:

給定的 n 保證是有效的。

進階:

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


題解:

法一:

兩次遍歷。

第一次遍歷統計節點數量 len ,第二次遍歷到底 len-n 個節點時停止,然後刪除節點即可。

注意刪除頭節點的情況。

法一程式碼:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { int len = 0; ListNode *p = head; while ( p ) { ++len; p = p->next; } if ( len == n ) return head->next; int k = 0; for ( p = head; p; p =
p->next ) { ++k; if ( k == len - n ) { p->next = p->next->next; break; } } return head; } }; /* 時間:4ms,擊敗:93.00% 記憶體:10.3MB,擊敗:99.87% */
法二:

一次遍歷。該方法流程如下:

  • first 指標從 head 開始走 n
  • second 指標從 head 開始和 first 同步更新
  • first 指標為空時停止

若是不帶頭節點的連結串列,則在 first 指標走 n 步後,若其為空,需要刪除的是 head 節點,處理一下即可。

若是帶頭節點的連結串列,那麼 head 可以當做普通節點操作,很方便。

不帶頭節點:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *first = head;
        int k = 0;
        while ( k < n ) {
            first = first->next;
            ++k;
        }
        if ( !first ) return head->next;
        ListNode *second = head, *pre = NULL;
        while ( first ) {
            first = first->next;
            pre = second;
            second = second->next;
        }
        pre->next = second->next;
        return head;
    }
};
/*
時間:0ms,擊敗:100.00%
記憶體:10.5MB,擊敗:97.29%
*/

帶頭節點:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *dummy = new ListNode();
        dummy->next = head;

        ListNode *first = dummy;
        for ( int i = 0; i <= n; ++i ) first = first->next;
        ListNode *second = dummy;
        while ( first ) {
            first = first->next;
            second = second->next;
        }
        second->next = second->next->next;
        return dummy->next;
    }
};
/*
時間:0ms,擊敗:100.00%
記憶體:10.2MB,擊敗:99.99%
*/