2024/5/20 小满,花未全开月未圆,半山微醉尽余欢。何须多虑盈亏事,终归小满胜万全。凡事只求半称心就好啦!做题!
1、题目描述
2、逻辑分析
题目要求理解了,但是不知道什么方法来求解。看题解先。题解给出了两种方案:哈希集合与双指针。先来看看哈希集合:
首先遍历链表A,将链表A中的每个节点加入到哈希集合中。然后遍历链表B,对于遍历到的每一个节点,判断该节点是否在哈希集合中:
- 如果当前节点不在哈希集合中,则继续遍历下一个节点;
- 如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链表的相交部分,因此在链表B 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,返回该节点。
如果链表 B 中的所有节点都不在哈希集合中,则两个链表不相交,返回 null。
3、代码演示
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> David = new HashSet<ListNode>();
ListNode temp = headA;
while(temp != null){
David.add(temp);
temp = temp.next;
}
temp = headB;
while(temp != null){
if(David.contains(temp)){
return temp;
}
temp = temp.next;
}
return null;
}
时间复杂度:O(n+m)(分别为链表A和链表B的长度),空间复杂度:O(n)(链表A的长度)。
再来看看双指针这一方法。真的天才,这玩意儿谁想出来的捏,天才哇。我来简述思路:
指针A、B分别指向链表A、链表B的头节点。分别遍历,如果指针A遍历完成后就指向链表B的头节点继续遍历,指针B也是同理。如果链表A和链表B相交,那么指针A一定会在相交的节点与B相遇。画图分析更为透彻。有点像蛇自己吃自己了,不过这个算法相当于两条蛇相互吃对方,最后碰头的场景。ok,代码演示一下:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null){
return null ;
}
ListNode A = headA;
ListNode B = headB;
while(A != B){
A = A == null? headB : A.next;
B = B == null? headA : B.next;
}
return A;
}
这个算法比第一种哈希集合在空间复杂度上更优,只有O(1)。
今天的第一道题就到这儿啦!再去学点其他的就到午饭时刻啦。两天没吃教师餐厅的菜,很想念。