一、思路
給定單鏈表,返回鏈表的中間結點。如果有兩個中間結點(總結點個數爲偶數),則返回第二個中間結點。舉例:
例子1:
輸入:[1,2,3,4,5]
輸出:結點 3
例子2:
輸入:[1,2,3,4,5,6]
輸出:結點 4
從以上兩個例子可以總結出全體,因爲結點個數非奇即偶。如果是數組的話,我們會利用下標間的關係——n/2即可(n爲數組元素個數),但是單鏈表不滿足隨機存取的要求(“遍歷”);我們同樣可以採用先遍歷一次鏈表獲取表長,然後再遍歷鏈表長度的一半(多一個還是少一個這種細節問題暫不討論)就可以了。
1.1 迭代分析
上文已經討論過了,先遍歷整條鏈表後遍歷一半的鏈表;那能不能二者同時發生呢?我們採用雙指針法,慢指針slow每趟走一步,快指針fast每趟走兩步;結束的時候,快指針遍歷了鏈表,慢指針恰恰遍歷了一半(時間相同速度減半導致路程減半)。
ListNode* middleNode(ListNode* head) {
if (!head || !head->next) { //鏈表爲空表或者只有1個結點
return head;
}
ListNode *slow = head, *fast = head->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return !fast ? slow : slow->next;
}