老规矩,题目如下:
这里将会介绍到一种新的算法思想,这里先酝酿一波。
看到题目,会想到之前xieC语言的时候类似的题目,思路清晰而明了:用计数器(count++)遍历链表,然后除2得到中间位置,然后使用for循环得到中间节点。
显然,在算法的简洁度方面,两个for循环还是有点多了,有没有可能改成一个for循环解决问题呢?
当然是有的,思路二/新的算法思想:
快慢指针法:定义两个指针,一个fast,一个slow,让fast一次走两个节点,slow一次走一个节点,当fast走到头的时候slow的位置就是中间节点,这样只用了一个循环,妙啊!
代码实现:
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
ListNode* Fast = head;
ListNode* Slow = head;
while (Fast && Fast->next)
{
//慢指针每次走一步,快指针一次走两步
Fast = Fast->next->next;
Slow = Slow->next;
}
//此时Slow恰好是中间节点
return Slow;
}
有个小细节:while(Fast && Fast->next)不能改成while(Fast->next && Fast),否则不会通过,但这两个有什么区别呢?
前者(正确答案)先执行Fast,当Fast为空时不再执行Fast->next,即发生了短路;但错误答案先执行Fast->next,这个时候如果Fast已经空了,就不存在Fast->next了,当然会报错。
希望我的代码可以帮到你,如果有什么问题或者建议欢迎在评论区讨论,谢谢支持~