LeetCode刷題系列19

2021-09-29 10:02:25 字數 1539 閱讀 4507

給定乙個鍊錶,刪除鍊錶的倒數第 n 個節點,並且返回鍊錶的頭結點。

示例:給定乙個鍊錶: 1->2->3->4->5, 和 n = 2.

當刪除了倒數第二個節點後,鍊錶變為 1->2->3->5.

說明:給定的 n 保證是有效的。

高階:你能嘗試使用一趟掃瞄實現嗎?

(1)方法一:

兩次遍歷演算法

思路我們注意到這個問題可以容易地簡化成另乙個問題:刪除從列表開頭數起的第(l - n + 1)個結點,其中l是列表的長度。

只要我們找到列表的長度l,這個問題就很容易解決。

演算法首先我們將新增乙個啞結點作為輔助,該結點位於列表頭部。啞結點用來簡化某些極端情況,例如列表中只含有乙個結點,

或需要刪除列表的頭部。在第一次遍歷中,我們找出列表的長度l。然後設定乙個指向啞結點的指標,並移動它遍歷列表,

直至它到達第(l−n)個結點那裡。我們把第(l−n)個結點的 next 指標重新鏈結至第 (l−n+2) 個結點,完成這個演算法。

/**

* definition for singly-linked list.

* struct listnode

* };

*/class solution

nlength -= n;

first = dummy;

while(nlength>0)

first->next = first->next->next;

return dummy->next;

}};

複雜度分析:

時間複雜度:o(l),該演算法對列表進行了兩次遍歷,首先計算了列表的長度l其次找到第(l−n)個結點。 操作執行了2l−n步,時間複雜度為o(l)。

空間複雜度:o(1),我們只用了常量級的額外空間。

(2)方法二:

演算法

上述演算法可以優化為只使用一次遍歷。我們可以使用兩個指標而不是乙個指標。第乙個指標從列表的開頭向前移動 n-1步後,

判斷結點next是否到達末尾,如果到達末尾則需要刪除的是第乙個元素,直接返回head->next就行了;如果結點next沒有

到達末尾,第二個指標將從列表的開頭出發。現在,這兩個指標被n個結點分開。我們通過同時移動兩個指標向前來保持這

個恆定的間隔,直到第乙個指標到達最後乙個結點。此時第二個指標將指向從最後乙個結點數起的第n個結點。我們重新鏈

接第二個指標所引用的結點的 next 指標指向該結點的下下個結點。

/**

* definition for singly-linked list.

* struct listnode

* };

*/class solution

backward->next = backward->next->next;

return head;

}};

複雜度分析

時間複雜度:o(l),該演算法對含有l個結點的列表進行了一次遍歷。因此時間複雜度為o(l)。

空間複雜度:o(1),我們只用了常量級的額外空間。

leetcode刷題筆記19

面試題28.對稱的二叉樹 請實現乙個函式,用來判斷一棵二叉樹是不是對稱的。如果一棵二叉樹和它的映象一樣,那麼它是對稱的。definition for a binary tree node.class treenode def init self,x self.val x self.left none...

leetcode刷題系列

題目 輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。解題思路 如果乙個整數不為0,那麼這個整數至少有一位是1。如果我們把這個整數減1,那麼原來處在整數最右邊的1就會變為0,原來在1後面的所有的0都會變成1 如果最右邊的1後面還有0的話 其餘所有位將不會受到影響。舉個例子 乙個二進...

LeetCode刷題系列1

給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。你可以假設每種輸入只會對應乙個答案。但是,你不能重複利用這個陣列中同樣的元素。示例 給定 nums 2,7,11,15 target 9 因為 nums 0 nums 1 2 ...