算法---LeetCode 160. 相交链表(剑指offer 52)

1. 题目

原题链接
剑指 Offer 52. 两个链表的第一个公共节点

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

在节点 c1 开始相交。

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], s
kipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表
,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA =
1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表
]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, sk
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersect
skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。

注意:

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

2. 题解

2.1 解法1: 双指针

  1. 创建两个指针 pA 和 pB,分别初始化为链表 A 和 B 的头结点。然后让它们向后逐结点遍历
  2. 当 pA 到达链表的尾部时,将它重定位到链表 B 的头结点 ; 类似的,当 pB 到达链表的尾部时,将它重定位到链表 A 的头结点。
  3. 若在某一时刻 pA 和 pB 相遇,则 pA/pB 为相交结点。
  4. 循环结束条件为 pA==pB, 当两者同时为null 时, 没有交点
    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            if (headA == null || headB == null) return null;
            ListNode pA = headA, pB = headB;
            while (pA != pB) {
                pA = pA == null ? headB : pA.next;
                pB = pB == null ? headA : pB.next;

            }
            return pA;// 若pa 为 null ,说明没有交点
        }
    }

写法2:

    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            if (headA == null || headB == null) {
                return null;
            }
            ListNode pA = headA, pB = headB;
            while (pA != pB) {
                if (pA != null) {
                    pA = pA.next;
                } else {
                    pA = headB;
                }
                if (pB != null) {
                    pB = pB.next;
                } else {
                    pB = headA;
                }
            }
            return pA;
        }
    }

2.2 解法2: 哈希表

   /**
     * 思路2 : 先遍历一遍链表 A ,用哈希表存储节点,
     * 然后遍历链表 B, 若有相同的元素则返回
     */
    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            if (headA == null || headB == null) {
                return null;
            }
            Set<ListNode> nodeSet = new HashSet<>();
            ListNode pA = headA, pB = headB;
            while (pA != null) {
                nodeSet.add(pA);
                pA = pA.next;
            }
            while (pB != null) {
                if (nodeSet.contains(pB)) {
                    return pB;
                }
                pB = pB.next;
            }
            return null;


        }
    }

参考:
官方题解

你可能感兴趣的:(算法,剑指offer,链表,链表,数据结构,java)