被滴滴小姐姐摁在地上摩擦
前段时间正在找工作,有幸接到滴滴的面试邀请,结果因为一个链表问题被摁在地上摩擦。
开始聊从项目、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 刷题,大部分都是在刷熟练度(板砖别砸我),而常常忽略了本质。想起老师叮嘱的话:要知其然,还要知其所以然。