题目
leetcode-cn.com/problems/in… 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
思路1
两个指针A、B,让这俩指针都走一遍headA+headB,如果有交点,肯定会相遇(因为如果有交点,交点之后的路程肯定是一样的,然后俩指针又走一样的总路程headA+headB,所以如果相遇,一定在交点。)
代码1
这一题可以不用写边界,但是最好每题一开始都写一下边界。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null){
return null;
}
ListNode A = headA,B = headB;
while (A != B){
A = A == null ? headB : A.next;
B = B == null ? headA : B.next;
}
return A;
}
}
上面的代码是看了评论改进的,真的是优雅。一开始根据思路写的代码是这样的:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA,B = headB;
while (A != B){
while(A != null && B != null){
A = A.next;
B = B.next;
}
if (A == null){
A = headB;
}
if (B == null){
B = headA;
}
}
return A;
}
}
多个循环嵌套,超出了时间限制,(按理说应该是O(n^2),怎么会超限制呢?)
思路2
一个很巧的思路,就是先让一个链表成环,然后在快慢指针判断环,相遇返回交点。最后记得复原链表。环找环起点刚好有一题,放下一题再将吧。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null){
return null;
}
ListNode A = headA ;
while(A.next != null){
A = A.next;
}
A.next = headA;
ListNode fast = headB;
ListNode slow = headB;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast){
slow = headB;
while(slow != fast){
slow =slow.next;
fast = fast.next;
}
A.next = null;
return slow;
}
}
A.next = null;
return null;
}
}