被滴滴小姐姐摁在地上摩擦
前段时间正在找工作,有幸接到滴滴的面试邀请,结果因为一个链表问题被摁在地上摩擦。
开始聊从项目、go 到 mysql 等方面聊得很愉快,最后小姐姐出了一道链表问题。
问题描述
滴滴小姐姐: 给链表判断是否有环?(心中暗喜,闭着眼都能写出来)
思路:快慢指针, 刷刷写完
1 | /** |
滴滴小姐姐: 如果有链表有环,请用数学证明快慢指针一定能相遇。

现在想想真的很丢脸(无地自容),花了两个小时终于搞明白了。
分析

如上图
假设链表又环,fast在 node7 的时候,slow 进入 入环点 node3。
数学推导:
- 假设
fast到slow距离为N,fast比slow快一步。 - 所以每走一步,两点距离:N+1-2 = N-1。
- 一直到
N = 0的时候,两个指针相遇。
总结: fast 多走 1 步、2 步、n 步都没有关系,因为两个指针的距离在缩短,相遇是必然的。
继续延伸: 链表入环点
滴滴小姐姐(已下线): 如果一个链表有环,请返回入环点。
1 | /** |
滴滴小姐姐(已下线): 请用数学证明:第一次相遇的点到入环点的距离等于从头指针到入环点的距离。

证明过程:
- 链表
头结点到入环点的距离为a, 入环点到两个指针第一次相遇的点的距离为b- 两个指针
第一次相遇的点再到入环点的距离为c fast= a + b + c + bslow= a + b- 由于
fast是slow的两倍速度, - 2(a+b) = a + b + c + b
-> 2a + 2b = a + c + 2b
-> 2a = a + c
-> a = c - 所以,第一次相遇的点到入环点的距离等于从头指针到入环点的距离。
fast指针只能比slow指针多走一步。fast多走几步没法成立。
复盘
在 leet code 刷题,大部分都是在刷熟练度(板砖别砸我),而常常忽略了本质。想起老师叮嘱的话:要知其然,还要知其所以然。