每隔k次反轉一次 鍊錶 輕鬆搞定鍊錶反轉

2021-10-14 05:26:29 字數 2121 閱讀 5557

最近迫於生活,又去面試咯。好在魔都的就業環境還可以,面試機會總是不缺。今天閒下來了,來談一談我最近面試遇到的一道題,是跟反轉鍊錶相關的。

題目很簡潔:給定乙個鍊錶的head跟數字k,反轉從head開始的交替間隔的大小為k的子列表。也就是說,我反轉k個節點之後,跳過k個節點,再反轉k個節點,以此類推。反轉乙個鍊錶不複雜,但是通常我們遇到的題目會附加額外條件,比如:不允許開闢額外的記憶體空間。

我們先來看看反轉乙個鍊錶我們會怎麼做,我們的思路很直接,從頭開始依次取節點,讓它指向前面乙個節點,到最後我們的鍊錶就反轉完成了。**跟口述過程一樣簡單,我們直接來上**:

public static listnode reverse(listnode head) 

// 迴圈結束後,previous指向原鍊錶的最後乙個節點,此時它已經成為反轉後鍊錶的head

return previous;

}

我們只要儲存好下乙個要處理的節點的索引,保證可以按順序迭代,之後按照正常思路反轉引用就好。

好了,有了這道題的基礎,我們來增加一些難度,現在給定乙個數字k,反轉鍊錶中每個長度為k的子列表。也就是說,當k=2時,給我們乙個鍊錶1->2->3->4,反轉後變成2->1->4->3。現在看起來無從下手,其實跟上題區別不大,我們只要關注每過k個節點重新開始一輪反轉,其它的流程照舊即可。

public static listnode reverse(listnode head, int k) 

//跟前面的部分鏈結

if (lastnodeofpreviouspart != null)

lastnodeofpreviouspart.next = previous; // previous現在是子列表的第乙個節點

else // 這意味著我們在處理第乙個子列表

head = previous;

lastnodeofsublist.next = current;

if (current == null) //到達最後,結束迴圈

break;

// 為下乙個子列表做準備

previous = lastnodeofsublist;

}return head;

}

其實不管是要求我們反轉乙個子列表還是多個子列表,都沒問題。反轉多個子列表的時候,反轉過程是一樣的,需要注意的點無非是在各個子列表反轉後的前後鏈結,我們只要記住每個子列表開頭跟結束的節點,在反轉完成的時候進行鏈結就好了。

現在我們可以回到開頭的問題了,這道題跟上面那道區別也很小哇,好巧啊!(手動狗頭 ,我才不說我是故意的)這邊唯一的區別在於我們得跳過k個節點。管它呢,我們還可以遵循上面那個流程,只不過在每次迭代後,跳過k節點,這不就行了嘛!

public static listnode reverse(listnode head, int k) 

// 跟前面的部分鏈結

if (lastnodeofpreviouspart != null)

lastnodeofpreviouspart.next = previous;

// 'previous'現在是子列表的第乙個節點

else //

head = previous;

// 與後面的部分鏈結

lastnodeofsublist.next = current;

// 跳過k個節點

for (int i = 0; current != null && i < k; ++i)

if (current == null) // 到最後了,結束迴圈

break;

}return head;

}

只要在最後加上跳過的邏輯,齊活兒!整個過程中,我們只迭代一次鍊錶,時間複雜度為o(n),而因為我們沒有開闢額外的記憶體空間,空間複雜度為o(1)。

到這裡可以發現,反轉鍊錶的問題一點也不難,很直接很暴力,也沒有像其他問題所說的什麼奇技淫巧,按照自己常規思路來就好咯。變來變去無非是變著花樣反轉子列表,只要大家想明白了它就變不出啥么蛾子了。

一文輕鬆搞懂 鍊錶反轉

單鏈表反轉 時間複雜度o n 空間複雜度o 1 的方法主要有以下三種 前情提要 設定乙個鍊錶,帶有頭結點。元素為1 2 3 4 倒轉過來應該是 1.頭插法 從第二個元素開始,每次選取乙個元素插入到頭結點和第乙個節點之間。第一步 把2插到head和1之間 第二步 把3插入head與2之間 第三步 把4...

鍊錶演算法 k個一組反轉鍊錶

如題,將鍊錶中的元素 k 個為一組,組內進行反轉,不夠 k 個的不反轉。例如 題目本身很容易理解 資料結構 private static class listnode 首先,需要乙個子函式,用於鍊錶逆序。這個算是寫爛了的題目了,但是一般都是用非遞迴來解決的,三個指標,一步一步逆序。但遞迴做更簡潔,不...

鍊錶翻轉(每K個結點進行一次逆置)

鍊錶翻轉 給出乙個鍊錶和乙個數k,比如鍊錶1 2 3 4 5 6 若k 2,翻轉後2 1 4 3 6 5,若k 3,翻轉後3 2 1 6 5 4,若k 4,翻轉後4 3 2 1 5 6,用程式實現node rotatelist node list,size t k 我的思路是把每k個結點的逆置成的鍊...