归纳编程学习的感悟,
记录奋斗路上的点滴,
希望能帮到一样刻苦的你!
如有不足欢迎指正!
共同学习交流!
🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言📝
每一个裂缝都是为透出光而努力!
法一:
这道题最朴素的做法是,先遍历一次,计算链表的长度,进而计算链表中间结点的下标(注意偶数结点的时候,得到的是中间的第二个结点),然后再遍历一次,来到所要求结点的位置。
缺点:
必须先遍历完整个链表,然后才可以「干正事」,再遍历到一半,找到中间结点;
在链表的长度很长的时候,这种方法之前的等待会很久
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode LNode;
typedef struct ListNode* LinkList;
struct ListNode* middleNode(struct ListNode* head) {
LNode *p;
p=head;
int count=1;
while(p->next)
{
p=p->next;
count++;
}
p=head;
int i=1;
while(i!=(count/2)+1)
{
p=p->next;
i++;
}
return p;
}
法二:
快慢指针:比较经典的做法是:
使用两个指针变量,刚开始都位于链表的第 1 个结点,一个永远一次只走 1 步,一个永远一次只走 2 步,一个在前,一个在后,同时走。这样当快指针走完的时候,慢指针就来到了链表的中间位置。
思想是:快慢指针的前进方向相同,且它们步伐的「差」是恒定的,根据这种确定性去解决链表中的一些问题。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode LNode;
typedef struct ListNode* LinkList;
struct ListNode* middleNode(struct ListNode* head) {
LNode *fast,*slow;
fast=slow=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}