1. 程式人生 > >leetcode19--刪除連結串列中倒數第n個節點

leetcode19--刪除連結串列中倒數第n個節點

       友情提示,刷leetcode題目的時候,先刷支援率高的題目,這些題目的質量好,我現在按照top 100 like
這個列表中的順序刷題,先把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個節點了。
       圖示: