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


    题目链接

    题目描述:


    我的题解:

    方法一:双指针法

    思路分析:

    • 声明两个指针p1,p2 分别指向链表A、链表B。
    • 然后分别同时逐结点遍历
    • 当 p1 到达链表 headA 的末尾时,重新定位到链表 headB 的头结点;当 p2 到达链表 headB 的末尾时,重新定位到链表 headA 的头结点。
    • 如此,当它们相遇时,所指向的结点就是第一个公共结点。
      (p1 p2可以分别遍历完两条链表。同时开始,将可以保证同时遍历结束。又因一旦同时指向第一个相交节点时,剩下的节点数相同;故可以保证p1和p2能同时指向到第一个相交节点(即相遇))

    代码如下:

         public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    
            if (headA == null || headB == null) return null;
    
            ListNode p1 = headA;
            ListNode p2 = headB;
            int change =0; // 重定位到链表头的次数和
            while (p1 != p2) {
    
                if (p1.next == null) {
                    p1 = headB; // 重定位到另一链表头
                    change++;
                } else p1 = p1.next;
    
                if (p2.next == null) {
                    p2 = headA; // 重定位到另一链表头
                    change++;
                } else p2 = p2.next;
    
    
                if (change > 2) return null; // 两个指针均已遍历另一条链表了
            }
            return p1;
        }
    

    方法二:也是双指针,但先求链表长度,再同时移动

    思路分析:

    • 声明两个指针p1,p2 分别指向链表A、链表B。
    • 稍后做一定的处理后 会同时移动两个指针。
    • 此题中,可以保证两指针最后同时到达链表尾,那么,也就可以保证同时到达相交结点(如果有的话)。
    • 那么,如何保证呢?分别求出两条链表的长度,然后,让长链表对应的指针,先走几步(步数为多出来的节点数)。
    • 做完上一步的处理后,p1和p2再同时移动,便可同时到达链表尾,自然就可以保证同时到达相交节点了(如果有的话)。

    代码如下:

         public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    
            ListNode p1 = headA;
            ListNode p2 = headB;
            int len1 = getLength(headA);
            int len2 = getLength(headB);
    
            int different = len1 - len2;
            // 长的指针,先走different步
            if (different > 0) {    // headA 长
                for (int i = different; i > 0; i--) {
                    p1 = p1.next;
                }
            } else {    // headB长 或 同样长(different=0,不进for循环了)
                for (int i = -different; i > 0; i--) {
                    p2 = p2.next;
                }
            }
    
            // 接着, p1,p2同时移动。当 p1 p2指向同一节点时,该节点即为题目所求的相交节点
            while (p1!=null && p2!=null && p1 != p2) {
                p1 = p1.next;
                p2 = p2.next;
            }
    
            return p1;
        }
    
        private int getLength(ListNode head) {
            int cnt = 0;
            for (ListNode tmp = head; tmp !=null ; tmp = tmp.next) {
                cnt++;
            }
            return cnt;
        }
    
  • 相关阅读:
    建立一个能持续处理的C/S网络程序
    建立一个可以不停地接收客户端新的连接,但不能处理复杂的业务的C/S网络程序
    归并排序
    堆排序
    计数排序
    不要在PHP7中踩这些坑
    关于生活学习
    topthink/think-swoole 扩展包的使用 之 WebSocket
    PHP 三元运算符
    topthink/think-swoole 扩展包的使用 之 Task
  • 原文地址:https://www.cnblogs.com/duduwy/p/13379448.html
Copyright © 2011-2022 走看看