876.链表的中间结点
依旧是“力扣新手村”里的题,我的思路只有解法1,然而解法2更妙,学习学习!
解法1:单指针法
1.经过一次遍历求出链表的长度。
2.再次遍历找到链表的中间结点。
class Solution {
public:
ListNode* middleNode(ListNode* head) {
int size = 0; // 记录链表长度
ListNode* p = head;
// 第一次遍历求出链表长度
while (p) {
p = p->next;
size++;
}
// 再次遍历找到链表的中间结点
size = size / 2;
while (size--) {
head = head->next;
}
return head;
}
};
时间复杂度:\(O(N)\),其中\(N\)为链表结点数。
空间复杂度:\(O(1)\)。
解法2:双指针法
使用快慢指针的方法来解该题,慢指针走一步,快指针走两步,当快指针走到链表末尾时,慢指针所指链表结点即为链表中间结点。
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
时间复杂度:\(O(N)\),其中\(N\)为链表结点数。
空间复杂度:\(O(1)\)。