leetcode19--刪除連結串列中倒數第n個節點
阿新 • • 發佈:2019-01-05
友情提示,刷leetcode題目的時候,先刷支援率高的題目,這些題目的質量好,我現在按照top 100 like
這個列表中的順序刷題,先把hard以下的刷完。
今天的第二題:刪除連結串列中倒數第n個元素,要求最好是隻遍歷一遍。難度:中等。
L是指向當前連結串列中某個節點的指標,問題來了:L + n 會把指標移動到 L 後面的第 n 個節點嗎?連結串列的所有節點在記憶體中不一定是連續存放的阿,我這個 L + n 說不定就跑到其他程式的記憶體去了,這樣很危險,所以,要實現自己想的那個功能,這個 L + n還是要用迴圈實現:
但是仔細一想,這樣的程式碼,效率不夠高阿,尤其是對於資料比較大的時候,比如連結串列有1000個節點,要刪除倒數500個,那麼前面幾乎一半的節點都要做這個for迴圈,每個迴圈500次,顯然效率不高。於是又默默點開disscuss研究大佬的程式碼,每次到這個階段都覺得自己太笨了,做做題目還真好,以前完全沒這種感覺,還覺得自己有時候挺聰明的,但是現在天天被虐,不敢有半點的自誇了。這也是做題的一些好處把,程式設計師,如果堆疊API太久,離開了演算法,那就會變得不像程式設計師了。多多提高自己的程式設計師修養把。
大佬的演算法思路其實不復雜,思路如下:定義兩個指標,一個叫做slow,一個叫做 fast,fast就是跑在前面的,slow就是跑在後面的。你要找倒數第n(n是合理的輸入,不會超過連結串列長度)個對不對,那我先讓fast從連結串列頭往前跑n步,當fast站在第n個節點這個位置的時候,slow開始從起點跑,fast也同步從n跑,當fast到終點的時候,slow所在位置的下一個節點就是倒數第n個節點了。
圖示:
這個列表中的順序刷題,先把hard以下的刷完。
今天的第二題:刪除連結串列中倒數第n個元素,要求最好是隻遍歷一遍。難度:中等。
我:只遍歷一遍?但是不知道連結串列的長度,怎麼在一遍之內找到呢?(如果是第一次做這個題目的同學估計會和我有)相同的疑問把。所以,該怎麼搞呢?...想了很久,終於有個方案:假設我當前遍歷到第 i 個元素,
while(L) { if( L + n == null_ptr) { //那麼 L 就是要找的倒數第n這個元素了 } else L = L-next; }
L是指向當前連結串列中某個節點的指標,問題來了:L + n 會把指標移動到 L 後面的第 n 個節點嗎?連結串列的所有節點在記憶體中不一定是連續存放的阿,我這個 L + n 說不定就跑到其他程式的記憶體去了,這樣很危險,所以,要實現自己想的那個功能,這個 L + n還是要用迴圈實現:
Lnode* JumpToNodeN(int n , Lnode* L)
{
Lnode* r = L;
for(int i = 0; i < n; i++)
{
r = r->next;
}
}
呼叫這個函式,如果函式的返回值為null_ptr目的達到,看樣子是可以了。但是仔細一想,這樣的程式碼,效率不夠高阿,尤其是對於資料比較大的時候,比如連結串列有1000個節點,要刪除倒數500個,那麼前面幾乎一半的節點都要做這個for迴圈,每個迴圈500次,顯然效率不高。於是又默默點開disscuss研究大佬的程式碼,每次到這個階段都覺得自己太笨了,做做題目還真好,以前完全沒這種感覺,還覺得自己有時候挺聰明的,但是現在天天被虐,不敢有半點的自誇了。這也是做題的一些好處把,程式設計師,如果堆疊API太久,離開了演算法,那就會變得不像程式設計師了。多多提高自己的程式設計師修養把。
大佬的演算法思路其實不復雜,思路如下:定義兩個指標,一個叫做slow,一個叫做 fast,fast就是跑在前面的,slow就是跑在後面的。你要找倒數第n(n是合理的輸入,不會超過連結串列長度)個對不對,那我先讓fast從連結串列頭往前跑n步,當fast站在第n個節點這個位置的時候,slow開始從起點跑,fast也同步從n跑,當fast到終點的時候,slow所在位置的下一個節點就是倒數第n個節點了。
圖示: