编写一个程序,找到两个单链表相交的起始节点。

例如,下面的两个链表:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3
在节点 c1 开始相交。

注意:

如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。


思路

先处理边边角角的情况:

  • 有一条为空或者两条都为空,则返回null
  • 俩头节点相等,任意返回其一

先算出两条链表的长度 countA,count B,
然后算出差值,让长的链表先走这个差值,保证剩下的节点数与另一条一样多。
完了之后就同时走俩指针,有相等的就是交点,没有就返回null。

/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */

/** * @param {ListNode} headA * @param {ListNode} headB * @return {ListNode} */
var getIntersectionNode = function(headA, headB) {
  let p = headA,
      q = headB;
  if (!p || !q) return null;
  if (p === q) return p;
  let countA = 0, countB = 0;
  while (p !== null) {
    countA ++
    p = p.next
  }
  while (q !== null) {
    countB ++
    q = q.next
  }
  
  p = headA;
  q = headB;
  if (countA > countB) {
    for (let i = countB; i < countA; i++) p = p.next;
  } else if (countA < countB) {
    for (let i = countA; i < countB; i++) q = q.next;
  }
  
  while (p && q) {
    if (p === q) return p
    p = p.next;
    q = q.next;
  }
  
  return null;
};