[LeetCode题解]160. 相交链表 | 双指针 + 哈希表

方法一:双指针

解题思路

假设链表存在相交时,headA 的长度为 a + cheadB 的长度为 b + c。如果把 headA 连上 headBheadB 连上 headB 的话,当遍历这两个新链表时有:

[(a + c) + (b + c) = (b + c) + (a + c) ]

(a + c + b = b + c + a),就出现相交的位置,因为 c 是相交部分的长度。

假设链表不相交,那么最后也会“相交”,“相交”于链表的尾部,即 null

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode GetIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pa = headA, pb = headB;

        while(pa != pb) {
            pa = pa == null ? headB : pa.next;
            pb = pb == null ? headA : pb.next;
        }

        return pa;
    }
}

复杂度分析

  • 时间复杂度:(O(m+n)),其中 (m)headA 的长度, (n)headB 的长度。
  • 空间复杂度:(O(1))

方法二:哈希表

解题思路

两次遍历,第一次遍历把 headA 的节点放到哈希表里,然后第二次遍历 headB ,判断节点是否在哈希表里,如果在,就是相交的起始点。

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode GetIntersectionNode(ListNode headA, ListNode headB) {
        HashSet<ListNode> hash = new HashSet<ListNode>();

        ListNode cur = headA;
        while(cur != null) {
            hash.Add(cur);
            cur = cur.next;
        }

        cur = headB;
        while(cur != null) {
            if(hash.Contains(cur)) {
                break;
            }
            cur = cur.next;
        }

        return cur;
    }
}

复杂度分析

  • 时间复杂度:(O(m+n)),其中 (m)headA 的长度, (n)headB 的长度。
  • 空间复杂度:(O(m)),其中 (m)headA 的长度。
原文地址:https://www.cnblogs.com/liang24/p/14011819.html