#LeetCode每日一题【链表专题】
-
相交链表
https://leetcode-cn.com/problems/intersection-of-two-linked-lists/ -
分析
前面已经实现了环形链表,如何寻找入环的位置。这一道题可以看成是环形链表的衍生题,寻找链表相交的位置:- 构造环形,headA一轮遍历,首尾相接入环
- 此时就是一个环形链表寻找入环位置的题:使用双指针,一快一慢相遇之后,重置慢指针到起点在重新同时出发,在相遇则为入环位置:详见:
https://blog.youkuaiyun.com/shijiujiu33/article/details/122544237 - 需要注意的是,题目要求保持原链表结构不变,在找到相交位置之后,需要断环
-
实现
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 寻找两个链表相遇的位置
// 类似于环形链表,寻找入环的位置
// 第一次遍历,将A链表成环;然后就是一道环形链表的问题
// A一次走两步,B一次走一步;相遇之后,置其中一个为头节点,在同时走,再次相遇即为入环位置(相交位置)
if (headA == null || headB == null) {
return null;
}
ListNode temp = headA;
while (temp.next != null) {
temp = temp.next;
}
temp.next = headA;
ListNode left = headB, right = headB;
while (right != null && right.next != null) {
right = right.next.next;
left = left.next;
if (left == right) {
break;
}
}
left = headB;
while (right != null && right.next != null) {
if (left == right) {
// 断环(保证原结构不变)
temp.next = null;
return left;
}
left = left.next;
right = right.next;
}
// 断环(保证原结构不变)
temp.next = null;
return null;
}
LeetCode耗时:1ms
- 实现二
交替遍历,headA遍历完之后,从headB开始遍历;同时headB遍历完之后,从headA开始遍历,则他们相遇的位置定为相交点:
还是一道数学题
public ListNode getIntersectionNode02(ListNode headA, ListNode headB) {
// 交替遍历,headA遍历完之后,从headB开始遍历;同时headB遍历完之后,从headA开始遍历,则他们相遇的位置定为相交点
if (headA == null || headB == null) {
return null;
}
ListNode tempA = headA, tempB = headB;
// 没有相交点,则会在null=null相遇
while (tempA != tempB) {
tempA = tempA == null ? headB : tempA.next;
tempB = tempB == null ? headA : tempB.next;
}
return tempA;
}
LeetCode耗时:1ms
- 总结
善于将题目转换为自己熟悉的题型;
相交的位置可以转换为找入环的位置;