380. 两个链表的交叉
请写一个程序,找到两个单链表最开始的交叉节点。
样例
样例 1:
输入:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
输出:c1
解释:在节点 c1 开始交叉。
样例 2:
输入:
Intersected at 6
1->2->3->4->5->6->7->8->9->10->11->12->13->null
6->7->8->9->10->11->12->13->null
输出: Intersected at 6
解释:begin to intersect at node 6.
挑战
需满足 O(n) 时间复杂度,且仅用 O(1) 内存。
注意事项
-
如果两个链表没有交叉,返回null。
-
在返回结果后,两个链表仍须保持原有的结构。
-
可假定整个链表结构中没有循环。
超级巧妙的解,细品
参考https://leetcode-cn.com/problems/intersection-of-two-linked-lists/submissions/
这段代码叫: 无论谁先迈出第一步,对的人,总会相遇。
public class Solution {
/**
* @param headA: the first list
* @param headB: the second list
* @return: a ListNode
*/
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;
}
}
第二种方法: 编译一个链表到结尾,将结尾和其中一条链表链接,形成一个环,然后哦使用找环第一个节点的方法
public class Solution {
/**
* @param headA: the first list
* @param headB: the second list
* @return: a ListNode
*/
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null){
return null;
}
//知道A的结尾;
ListNode tailA = headA;
while(tailA.next != null){
tailA = tailA.next;
}
tailA.next = headA;
//知道第一个相遇点
ListNode ans = get(headB);
tailA.next = null;
return ans;
}
private ListNode get(ListNode head){
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(fast == slow){
while(head != slow){
head = head.next;
slow = slow.next;
}
return slow;
}
}
return null;
}
}
第一种方法: 使用set
public class Solution {
/**
* @param headA: the first list
* @param headB: the second list
* @return: a ListNode
*/
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null){
return null;
}
Set<ListNode> hashSet = new HashSet<>();
ListNode nodeA = headA;
while(nodeA != null){
hashSet.add(nodeA);
nodeA = nodeA.next;
}
ListNode nodeB = headB;
while(nodeB != null){
if(hashSet.contains(nodeB)){
return nodeB;
}
nodeB = nodeB.next;
}
return null;
}
}