LeetCode-19 删除链表的倒数第N个节点
文章目錄
- 題目描述
- 我的解法
- 反思
- 優(yōu)化
- 再次反思
- 再次優(yōu)化
- 總結(jié)
- Github
題目描述
給定一個(gè)鏈表,刪除鏈表的倒數(shù)第 n 個(gè)節(jié)點(diǎn),并且返回鏈表的頭結(jié)點(diǎn)。
示例:
給定一個(gè)鏈表: 1->2->3->4->5, 和 n = 2.
當(dāng)刪除了倒數(shù)第二個(gè)節(jié)點(diǎn)后,鏈表變?yōu)?1->2->3->5.
說(shuō)明:
給定的 n 保證是有效的。
進(jìn)階:
你能嘗試使用一趟掃描實(shí)現(xiàn)嗎?
我的解法
public ListNode removeNthFromEnd(ListNode head, int n) {ListNode current = head;List<ListNode> list = new ArrayList<ListNode>();while(current!=null){list.add(current);current = current.next;}int index = list.size()-n-1;//待刪除前一個(gè)nodeif(index==-1) {//說(shuō)明待刪除的是第一個(gè)nodereturn list.get(0).next;}list.get(index).next = list.get(index).next.next;return list.get(0);}用間:9ms
戰(zhàn)勝:91.31%
反思
最先想到的思路就是放到一個(gè)ArrayList里邊,遍歷一遍鏈表就有各自的順序了,然后找到list對(duì)應(yīng)序號(hào)結(jié)點(diǎn)的node,讓它指向下下個(gè)node。
但是這種方式無(wú)法將所有情況統(tǒng)一處理,不是出題者想考察的。
實(shí)際上,鏈表題目有一個(gè)固有的結(jié)題思路,就是在鏈表的頭部加一個(gè)dummy head(啞結(jié)點(diǎn))。如此,一些極端的情況(如鏈表只有一個(gè)結(jié)點(diǎn))就得以統(tǒng)一處理。
運(yùn)用這個(gè)思路,我們先嘗試兩次遍歷的算法。即,第一次遍歷鏈表的長(zhǎng)度,第二次遍歷到目標(biāo)結(jié)點(diǎn),使之指向下下個(gè)結(jié)點(diǎn)
優(yōu)化
public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0);dummy.next = head;int length = 0;ListNode first = head;while (first != null) {length++;first = first.next;}length -= n;first = dummy;while (length > 0) {length--;first = first.next;}first.next = first.next.next;return dummy.next; }復(fù)雜度分析
時(shí)間復(fù)雜度:O(L),
該算法對(duì)列表進(jìn)行了兩次遍歷,首先計(jì)算了列表的長(zhǎng)度 L 其次找到第 (L - n>)個(gè)結(jié)點(diǎn)。 操作執(zhí)行了 2L-n 步,時(shí)間復(fù)雜度為 O(L)。
空間復(fù)雜度:O(1),
我們只用了常量級(jí)的額外空間。
再次反思
題目在“進(jìn)階”處給出思考,能否用一次遍歷實(shí)現(xiàn)?答案肯定是能。如果我同時(shí)遍歷兩個(gè)鏈表,一個(gè)是從頭開(kāi)始遍歷,而另外一個(gè)呢是從頭開(kāi)始第n的結(jié)點(diǎn)開(kāi)始遍歷。那么,當(dāng)我遍歷完第二個(gè)鏈表時(shí),第一個(gè)鏈表更好遍歷到目標(biāo)結(jié)點(diǎn),將其next指向下下個(gè)結(jié)點(diǎn)即可。
再次優(yōu)化
public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode first = dummy;ListNode second = dummy;// Advances first pointer so that the gap between first and second is n nodes apartfor (int i = 1; i <= n + 1; i++) {first = first.next;}// Move first to the end, maintaining the gapwhile (first != null) {first = first.next;second = second.next;}second.next = second.next.next;return dummy.next; }復(fù)雜度分析
時(shí)間復(fù)雜度:O(L),
該算法對(duì)含有 L 個(gè)結(jié)點(diǎn)的列表進(jìn)行了一次遍歷。因此時(shí)間復(fù)雜度為 O(L)。
空間復(fù)雜度:O(1),
我們只用了常量級(jí)的額外空間。
總結(jié)
Github
LeetCode刷題筆記
總結(jié)
以上是生活随笔為你收集整理的LeetCode-19 删除链表的倒数第N个节点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: QQ HD有什么用(QQ官方下载)
- 下一篇: 无法访问虚拟机tomcat网页