LeetCode 中的單鏈表的結構定義一般是:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
1. 找到鏈表中間節點
示意:
1 -> [2] -> 3 # 鏈表長度爲奇數時,中間節點就是最中間的那個
1 -> [2] -> 3 -> 4 # 鏈表長度爲偶數時,中間結點是「前一半鏈表」的尾巴
[] # 空鏈表返回空(NULL)
方法:使用快慢指針:
/* 傳入鏈表的頭 head,返回鏈表中間結點 */
ListNode* endOfFirstHalf(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast->next && fast->next->next) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
2. 翻轉鏈表
示意:
1 -> 2 -> 3 ==> 3 -> 2 -> 1
方法:
/* 傳入舊鏈表的頭 head,返回新鏈表的頭 */
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
可以預見,對一個鏈表翻轉兩次,就復原了:
list == reverseList(reverseList(list))
這個性質有時候非常有用,比如你需要翻轉鏈表才能做一些事,但做完你要做的事以後,還應該把鏈表再翻轉回去,因爲最好不要修改原數據。
待更新