该题属于简单题
思路上,最容易想到的应该是单指针了
即我们先使用一个指针去遍历链表看有多少个结点,再根据题目要求,得到我们的目标(即哪个结点),最后再遍历一次链表,到了目标结点,就return或者break即可
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
int cn=0,target;
ListNode *ans;
for(ListNode *p=head;p;p=p->next)
{
cn++;
}
if(cn%2!=0)
target=(cn+1)/2;
else
target=cn/2+1;
cn=0;
for(ListNode *p=head;p;p=p->next)
{
cn++;
if(cn==target)
{
ans=p;
break;
}
}
return ans;
}
};
法2:空间换时间
我们也可创建一个数组来存储所有结构指针,最后只需输出下标为 数组大小/2 的那个结点即可
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
vector<ListNode*> num={head};//初始化
while(num.back()->next!=nullptr)//注意这里的back是选择数组中最后一个元素
{
num.push_back(num.back()->next);
}
return num[num.size()/2];
}
};
法3:快慢指针(最好方法)
我们可以继续优化方法1,用两个指针 slow 与 fast 一起遍历链表。slow 一次走一步,fast 一次走两步。那么当 fast 到达链表的末尾时,slow 必然位于中间。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public://快慢指针
ListNode* middleNode(ListNode* head) {
ListNode *fast=head;
ListNode *slow=head;
while(fast!=nullptr&&fast->next!=nullptr)
{
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
};