刪除鏈表的倒數第N個節點
一、LeetCode題解
瞧一瞧~
- 博健的LeetCode題解:Gitbook版本傳送門
- 博健的LeetCode題解:CSDN傳送門
- 有趣的CSS:Gitbook傳送門
- 前端進階筆記:Gitbook傳送門
二、算法題
題目
給定一個鏈表,刪除鏈表的倒數第 n 個節點,並且返回鏈表的頭結點。
示例:
給定一個鏈表: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.
說明:
給定的 n 保證是有效的。
進階:
你能嘗試使用一趟掃描實現嗎?
解法一(二次遍歷操作)
- 時間複雜度:O(n)
- 空間複雜度:O(1)
首先我們將添加一個啞結點
作爲輔助,該結點位於列表頭部。啞結點用來簡化某些極端情況,例如列表中只含有一個結點,或需要刪除列表的頭部。
- 在第一次遍歷中,我們找出列表的長度 L。
- 然後設置一個指向啞結點的指針,並移動它遍歷列表,直至它到達第 (L - n) 個結點。
- 把第 (L - n) 個結點的 next 指針重新鏈接至第 (L - n + 2)個結點。
代碼
var removeNthFromEnd = function(head, n) {
var current = head
var len = 0
while (current) {
len++
current = current.next
}
len = len - n
head = { val: '', next: head }
current = head
while (len != 0) {
current = current.next
len--
}
current.next = current.next.next
return head.next
}
結果
解法二(快慢指針)
- 快指針先跑到第n節點。
- 之後,慢指針從頭節點,與快指針同時走。
- 快指針走到尾部,慢指針指向了倒數第n個節點
代碼
var removeNthFromEnd = function(head, n) {
var current = { val: '', next: head }
var fast = current
var slow = current
for (let i = 1; i <= n + 1; i++) {
fast = fast.next;
}
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return current.next;
}