19-刪除連結串列的倒數第N個節點
阿新 • • 發佈:2020-11-16
題目:
給定一個連結串列,刪除連結串列的倒數第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/