面试技巧:链表是否有环,另一道是判断是否有环,另一道是找到环的起点。

环形链表这类题目,其实可以拆解为两道,一道是判断是否有环,另一道是找到环的起点。这种题通常作为面试的常客,主要是考验咱们在有限时间里的反应速度和代码能力。一般来说,面试官会先让你用哈希表的思路搞定第一题,确认链表是否成环,再让你用双指针法找到环的起点,最后可能还会追问一些数学原理。 对于链表是否存在环的问题,首先你得明白链表为什么会“长尾巴”。链表本来是条直线,可要是在尾巴处偷偷连一根指针回来,整条链就变成了一个圈,节点们就能绕着圈子跑了。面对这种变形的链表,面试官最想知道你能不能在短时间内识破它的伪装。 第一题通常是题目 141,也就是LinkedList Cycle(Easy)。输入是一个无序的链表头节点head,输出是一个布尔值,告诉你这链表到底有没有环。很多同学拿到题第一反应就是直接写个遍历代码,不停往下走。但问题是如果真遇到环了,程序就会像原地打转一样停不下来。这个时候面试官看你这么写,心里肯定是有想法的。 哈希表的思路虽然有点笨拙,但很稳妥。咱们可以把遍历过的所有节点都塞进一个HashSet里。如果后面又遇到重复的节点了,说明环已经被我们抓到了。这种方法时间复杂度和空间复杂度都是O(N),虽然稳准狠,但是面试官一般不会让你直接交卷。 那有没有更高效的办法呢?双指针法就派上用场了。咱们让一个快指针每次走两步,一个慢指针每次走一步。如果链表没环,快指针会先跑到终点;如果有环的话,快指针肯定能“套圈”追上慢指针。只要两个指针相遇了,就说明环存在。这种方法时间复杂度是O(N),空间复杂度是O(1),代码又简单又高效。 第二题难度稍微高一点,是题目 142——LinkedList Cycle II(Medium)。输入还是那个head节点,这次要求返回的是环的入口节点。如果链表没环的话就返回null。 数学证明比较复杂咱们先不深究,面试现场只要会写代码就行。当快慢指针第一次相遇后,咱们可以确定链表有环了。这时候再新开一个指针q从头结点出发,让它和慢指针以同样的速度前进。当q和慢指针再次相遇的时候,那个相遇点就是环的入口。 整个流程其实就是三步走:先判断有没有环——用双指针法最保险;再找环的起点——二次相遇的思路;最后总结套路——学会用不同的方法应对不同的难度梯度。 面试官通常按难度梯度来问:先是Easy的判断题,再是Medium的进阶题。观察你的反应速度和处理错误的能力很重要。遇到不会的问题别慌也别沉默,大方承认自己不会并引导面试官给出提示就行。节奏感对面试来说也是加分项。 祝大家下次面试都能环环相扣、步步高升!