链表相交问题

链表

链表相交问题

思路来源

一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到

笔记内容

  • 问题描述:

    现有两个单向链表,需要判断两个链表是否相交,若相交,返回链表最开始的交点,若不相交,则返回null

  • 算法思路:

    • 首先需要判断两个链表是否是环形链表,并获取环形链表的环开始点

    • 针对两个链表的不同情况进行分析:

      1. 若两个链表都不存在环,那么两个链表要么从头至尾都没有相交节点,要么从相交节点开始到结尾都是共用的;

      2. 若两个链表中存在一个环,那么两个链表不相交;

      3. 若两个链表都存在环,那么需要根据环开始点进行判断。如果是同一个开始点,那么两个链表必相交,相交点可能在该点前,视作第一种情况处理;如果开始点不同,相交点可能在环内或者不相交。

  • 代码实现

    class ListNode {
        int val;
        ListNode next;
        ListNode() {}
        ListNode(int val) { this.val = val; }
        ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    }
    
    public static ListNode isMeet(ListNode head1,ListNode head2){
            ListNode loop1 = hasCycle(head1);
            ListNode loop2 = hasCycle(head2);
            if(loop2 == null && loop1 == null){ //两个无环
                int p = length(head1,null)-length(head2,null);
    
                loop1 = p > 0 ? head1 : head2 ;
                loop2 = loop1 == head1 ? head2 : head1;
                p = Math.abs(p);
                while (p>0){
                    loop1 = loop1.next;
                    p--;
                }
                while (loop2 != null && loop1 != null){
                    if(loop2 == loop1){
                        return loop1;
                    }
                    loop1 = loop1.next;
                    loop2 = loop2.next;
                }
    
            }else if(loop2 == null || loop1 == null){ //存在一个有环
                return null;
            }else { //两个环
                if(loop2 == loop1){
                    int p = length(head1,loop1)-length(head2,loop2);
                    loop1 = p > 0 ? head1 : head2 ;
                    loop2 = loop1 == head1 ? head2 : head1;
                    p = Math.abs(p);
                    while (p>0){
                        loop1 = loop1.next;
                        p--;
                    }
                    while (loop2 != null && loop1 != null){
                        if(loop2 == loop1){
                            return loop1;
                        }
                        loop1 = loop1.next;
                        loop2 = loop2.next;
                    }
    
                }else {
                    ListNode cur = loop1.next;
                    while (cur != loop1){
                        if(cur == loop2){
                            return loop1;
                        }
                        cur = cur.next;
                    }
                }
    
            }
            return null;
    
        }
    
        public static int length(ListNode head,ListNode end){
            int count = 0;
            if(end == null){
                while (head != null){
                    count++;
                    head = head.next;
                }
            }else {
                while (head != end){
                    count++;
                    head = head.next;
                }
            }
            return count;
        }
    
        //快慢指针
        public static ListNode hasCycle(ListNode head) {
            if(head == null || head.next == null || head.next.next == null){
                return null;
            }
            ListNode slow = head.next;
            ListNode fast = head.next.next;
            while (slow != fast){
                if(fast.next == null || fast.next.next == null){return null;}
                slow = slow.next;
                fast = fast.next.next;
            }
            fast = head;
            while (slow != fast){
                fast = fast.next;
                slow = slow.next;
            }
            return fast;
        }
    
posted @ 2023-12-31 13:44  Noule  阅读(5)  评论(0编辑  收藏  举报