[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 的长度。
posted @ 2020-11-20 16:57  大杂草  阅读(202)  评论(0编辑  收藏  举报