解法1:快慢指针。快指针每次走2步,慢指针每次一步。快指针到末尾时,慢指针即指向重点。
/**
* Definition of ListNode
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param head: the head of linked list.
* @return: a middle node of the linked list
*/
ListNode * middleNode(ListNode * head) {
ListNode* p1=head;
ListNode* p2=head;
if (!head) return NULL;
while(p2&&p2->next) {
p2=p2->next;
if (p2->next) {
p1=p1->next;
p2=p2->next;
}
}
return p1;
}
};
注意特殊情形如1->2->NULL。所以应该p2先移动,看还没有移到末尾,再同时移动p1和p2。
另一个稍微简单些的版本如下:
ListNode * middleNode(ListNode * head) {
if (!head || !head->next) return head;
ListNode* p1=head;
ListNode* p2=head->next;
while(p2&&p2->next) {
p1=p1->next;
p2=p2->next->next;
}
return p1;
}
准备把上面这个当模板了。
注意:不同平台对middle的定义不一样,比如说{1,2,3,4,5,6} LintCode认为3是middle, LeetCode认为4是middle。
上面这个模板对Leetcode的版本如下:
class Solution {
public:
ListNode* middleNode(ListNode* head) {
if (!head || !head->next) return head;
ListNode * slow = head, * fast = head->next;
while(fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
if (fast && !fast->next) return slow->next;
return slow;
}
又写了一遍,这种写法也可以:
class Solution {
public:
ListNode * middleNode(ListNode * head) {
if (!head) return NULL;
if (!head->next || !head->next->next) return head;
ListNode *p1 = head, *p2 = head;
while(p2->next && p2->next->next) {
p2 = p2->next->next;
p1 = p1->next;
}
return p1;
}
};