请写一个程序,找到两个单链表最开始的交叉节点。
注意事项
如果两个链表没有交叉,返回
null
。
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
样例
下列两个链表:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
在节点 c1 开始交叉。
挑战
需满足 O(n) 时间复杂度,且仅用 O(1) 内存
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
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 node = headA;
while (node.next != null) {
node = node.next;
}
// 链表 A 的尾结点和链表 B 的头结点连在一起
node.next = headB;
ListNode result = listCycleII(headA);
return result;
}
// 寻找带环链表的环的入口
private ListNode listCycleII(ListNode head) {
ListNode slow = head, fast = head.next;
// 先判断是否存在环
while (slow != fast) {
if (fast == null || fast.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
slow = head;
// 注意此处 fast 前进一个结点
fast = fast.next;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
网友评论