大家好呀,我是直男蛋。
今天来做相交链表,这道题本来是难度简单的水题,但是有两个奇怪点把我给整楞了。
一个就是题意,另一个就是解题方式,感觉直接把我的直男属性给暴露了。
具体的到下面细聊,现在先开始看题。
LeetCode 160:相交链表
题意
给出两个单链表的头节点,找出两个单链表相交的起始节点。
示例
提示
题目保证不存在环。
-
len(listA) = m, len(listB) = n
-
0 <= m, n <= 3 * 10^4
-
1 <= Node.val <= 10^5
-
0 <= skipA <= m, 0 <= skipB <= n
题目解析
在说我的解法之前,我先来说一下文章开头我说的是啥意思。
这个题目一开始题意给我看楞了,不看示例,打眼看上去还以为是找数值相等的节点。
估计很多臭宝容易看懵,这道题其实是找相交节点的指针(即同一节点,引用完全相同),而不是单纯遍历找第一个数值相同的节点,这点大家要搞清楚。
光这个出题的题意,我感觉就得值个难度 hard!
其实搞清楚了题意,稍微一想解法就能出来。
在我劈里啪啦的敲完代码然后 AC 的时候,随意点开了力扣的题解区,官方的题解给我看楞了。
虽然用了双指针,但是它的解法楞是用上了数学的思想。怕你们在做的时候会先去看题解,然后又看不懂别人怎么个思想,所以这里就给臭宝们讲一下**“浪漫”的做法**。
官方的方法是:
- 链表 A 的指针 flagA 从链表 A 的头节点开始遍历完链表 A,再遍历链表 B
- 链表 B 的指针 flagB 从链表 B 的头节点开始遍历完链表 B,再遍历链表 A
这样的话就消除了链表 A 和 B 的长度差。
假设链表 A 长度为 a,链表 B 长度为 b,两个链表相交的部分长度为 c。
当走到相交节点时:
- flagA 走过的长度为:a + (b - c)
- flagB 走过的长度为:b + (a - c)
这种做法,不管两个指针是否相交,他们走过的长度都是一样的,所以就有了公式:
a + ( b − c ) = b + ( a − c