206. 92. 25 | 翻轉(zhuǎn)鏈表 LeetCode
? 翻轉(zhuǎn)鏈表,可以通過迭代或者遞歸來實(shí)現(xiàn),但更好的辦法是使用原地翻轉(zhuǎn)算法。這種思想通常是利用額外的指針來保存當(dāng)前(或下一個)結(jié)點(diǎn)的信息來實(shí)現(xiàn)的。每次只翻轉(zhuǎn)一個節(jié)點(diǎn)。
定義一個額外的指針,指向當(dāng)前節(jié)點(diǎn)(cur)的下一個節(jié)點(diǎn)(next)
將當(dāng)前節(jié)點(diǎn)(cur)指向上一個節(jié)點(diǎn)(pre)
當(dāng)前節(jié)點(diǎn)(cur)和上一個節(jié)點(diǎn)(pre)往前移動一個節(jié)點(diǎn)(pre = cur;cur = next;)






分析:
??從題干可知,題目要求翻轉(zhuǎn)一個鏈表中的某一段鏈表,而不改變鏈表其他部分。
? 我們可以將其拆分成幾個步驟:
先遍歷鏈表,找到m節(jié)點(diǎn)的位置
單獨(dú)翻轉(zhuǎn)位置m到位置n的鏈表段
將翻轉(zhuǎn)后的鏈表段和原鏈表其余節(jié)點(diǎn)連接起來
步驟1和步驟2相對比較簡單,只需要按照206.的思路編碼即可。步驟3需要考慮以下幾種情況:
翻轉(zhuǎn)鏈表后,尾部節(jié)點(diǎn)是否存在未動過的節(jié)點(diǎn)?
[1,2,3,4,5], m = 2, n = 4, 此時5未被動過,需把2指向5,1指向4
[1,2,3,4,5], m = 2, n = 5, 此時5也被翻轉(zhuǎn),因此2指向nullptr
頭部節(jié)點(diǎn)是否被翻轉(zhuǎn)了?
[1,2,3,4,5], m = 1, n = 4, 由于1翻轉(zhuǎn)后指向5,因此head需要重新指向4
若m > 1,則只需要把1指向翻轉(zhuǎn)后的鏈表頭部即可

? 繼續(xù)觀察我們可以發(fā)現(xiàn),在步驟2結(jié)束后,若最后一個節(jié)點(diǎn)也被翻轉(zhuǎn),則cur == nullptr,所以我們可以將這一步的代碼優(yōu)化:



分析:
? 結(jié)合上面兩題來解答,首先遍歷k個節(jié)點(diǎn),找到需要翻轉(zhuǎn)的那組節(jié)點(diǎn),然后翻轉(zhuǎn)它,再為翻轉(zhuǎn)后的鏈表段接上頭和尾。注意,最后如果剩余節(jié)點(diǎn)小于k的話,則不做任何處理。
找到需要翻轉(zhuǎn)的k鏈表段
翻轉(zhuǎn)k鏈表段
將k鏈表段拼接回原鏈表
