zoukankan      html  css  js  c++  java
  • 剑指offer52 两个链表的第一个公共节点

    输入两个链表,找出它们的第一个公共节点。

    如下面的两个链表

    在节点 c1 开始相交。

    示例 1:

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

    示例 2:

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

    示例 3:

    输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
    输出:null
    输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
    解释:这两个链表不相交,因此返回 null。
    
    • 如果两个链表没有交点,返回 null.
    • 在返回结果后,两个链表仍须保持原有的结构。
    • 可假定整个链表结构中没有循环。
    • 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

    双指针

    方法1:先遍历两个长度,然后先遍历长的,距离为两个链表长度之差,然后对两个链表同时遍历

    /**
     * 方法1:先遍历两个长度,然后先遍历长的,距离为两个链表长度之差,然后对两个链表同时遍历
     *
     * @param headA
     * @param headB
     * @return
     */
    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) return null;
    
        ListNode pA = headA;
        int cntA = 0;
        while (pA != null) {
            pA = pA.next;
            cntA++;
        }
        ListNode pB = headB;
        int cntB = 0;
        while (pB != null) {
            pB = pB.next;
            cntB++;
        }
    
        ListNode listNodeF = cntA >= cntB ? headA : headB;
        ListNode listNodeS = cntA >= cntB ? headB : headA;
        int len = cntA >= cntB ? cntA - cntB : cntB - cntA;
        while (len > 0 && listNodeF != null) {
            len--;
            listNodeF = listNodeF.next;
        }
        // 两指针可以同时指向同一节点,包括null,也有可能其一指向null,另一个不指向null
        while (listNodeS != null || listNodeF != null) {
            if (listNodeF == listNodeS) return listNodeF;
            listNodeF = listNodeF.next;
            listNodeS = listNodeS.next;
        }
        return null;
    }
    

    方法2:双指针同时遍历两个链表,如果遍历到为空,则指向另一个链表,相遇位置即为第一个公共节点

    /**
     * 方法2:双指针同时遍历两个链表,如果遍历到为空,则指向另一个链表,相遇位置即为第一个公共节点
     *
     * @param headA
     * @param headB
     * @return
     */
    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) return null;
    
        ListNode listNodeP = headA;
        ListNode listNodeQ = headB;
        while (listNodeP != listNodeQ) {
            listNodeP = listNodeP != null ? listNodeP.next : headB;
            listNodeQ = listNodeQ != null ? listNodeQ.next : headA;
        }
        return listNodeP;
    }
    

    测试用例

    public static void main(String[] args) {
        // listA=[0,9,1,2,4],listB = [3,2,4],
        ListNode headA = new ListNode(0);
        ListNode headA2 = new ListNode(9);
        headA.next = headA2;
        ListNode headA3 = new ListNode(1);
        headA2.next = headA3;
        ListNode headA4 = new ListNode(2);
        headA3.next = headA4;
        ListNode headA5 = new ListNode(4);
        headA4.next = headA5;
    
        ListNode headB = new ListNode(3);
        headB.next = headA4;
    
        ListNode listNode = getIntersectionNode(headA, headB);
        if (listNode != null) {
            System.out.println("GetIntersectionNode52 demo01 result:" + listNode.val);
        }
    
        // listA = [4,1,8,4,5], listB = [5,0,1,8,4,5],
        headA = new ListNode(4);
        headA2 = new ListNode(1);
        headA.next = headA2;
        headA3 = new ListNode(8);
        headA2.next = headA3;
        headA4 = new ListNode(4);
        headA3.next = headA4;
        headA5 = new ListNode(5);
        headA4.next = headA5;
    
        headB = new ListNode(5);
        ListNode headB2 = new ListNode(0);
        headB.next = headB2;
        ListNode headB3 = new ListNode(1);
        headB2.next = headB3;
        headB3.next = headA3;
        listNode = getIntersectionNode(headA, headB);
        if (listNode != null) {
            System.out.println("GetIntersectionNode52 demo02 result:" + listNode.val);
        }
    }
    
  • 相关阅读:
    环境是如何建立的 启动文件有什么
    环境中存储的是什么
    串行 并行 异步 同步
    TPC-H is a Decision Support Benchmark
    进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道
    删除环境变量
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
  • 原文地址:https://www.cnblogs.com/fyusac/p/15039489.html
Copyright © 2011-2022 走看看