Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

0%

# Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析

发表于 2021-01-10 更新于 2022-06-11 分类于 Java ， leetcode ， Linked List ， java ， Linked List 阅读次数： 阅读次数： Disqus：

## 题目介绍

写一个程序找出两个单向链表的交叉起始点，可能是我英语不好，图里画的其实还有一点是交叉以后所有节点都是相同的
Write a program to find the node at which the intersection of two singly linked lists begins.

For example, the following two linked lists:
begin to intersect at node c1.

### Example 1:

    Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
    Output: Reference of the node with value = 8
    Input Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B.

## 分析题解

一开始没什么头绪，感觉只能最原始的遍历，后来看了一些文章，发现比较简单的方式就是先找两个链表的长度差，因为从相交点开始肯定是长度一致的，这是个很好的解题突破口，找到长度差以后就是先跳过长链表的较长部分，然后开始同步遍历比较 A，B 链表；

### 代码

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            if (headA == null || headB == null) {
                return null;
            }
            // 算 A 的长度
            int countA = 0;
            ListNode tailA = headA;
            while (tailA != null) {
                tailA = tailA.next;
                countA++;
            }
            // 算 B 的长度
            int countB = 0;
            ListNode tailB = headB;
            while (tailB != null) {
                tailB = tailB.next;
                countB++;
            }
            tailA = headA;
            tailB = headB;
            // 依据长度差，先让长的链表 tail 指针往后移
            if (countA > countB) {
                while (countA > countB) {
                    tailA = tailA.next;
                    countA--;
                }
            } else if (countA < countB) {
                while (countA < countB) {
                    tailB = tailB.next;
                    countB--;
                }
            }
            // 然后以相同速度遍历两个链表比较
            while (tailA != null) {
                if (tailA == tailB) {
                    return tailA;
                } else {
                    tailA = tailA.next;
                    tailB = tailB.next;
                }
            }
            return null;
        }

### 总结

可能缺少这种思维，做的还是比较少，所以没法一下子反应过来，需要锻炼，我的第一反应是两重遍历，不过那样复杂度就高了，这里应该是只有 O(N) 的复杂度。