两个链表第一个相交节点问题

public class test13 {
    public static class Node{
        public int value;
        public Node next;

        public Node (int data){
            this.value = data;
        }
    }

    public static Node getIntersectNode(Node head1 , Node head2){
        if(head1 ==null || head2 ==null ){
            return null;
        }
//找出第一个链表的入环节点
        Node loop1 = getLoopNode(head1);
//找出第二个链表的入环节点
        Node loop2 = getLoopNode(head2);
        
        //两个无环
        if(loop1 ==null && loop2 ==null){
//返回两个无环链表的相交节点
            return noLoop(head1  , head2);
        }
        
        //两个有环
        if (loop1 != null && loop2 != null){
//返回两个有环链表的相交节点
            return bothLoop(head1 , loop1 , head2 ,loop2);
        }

        return null;


    }
    //找到第一个入环的节点,如果不为环返回null
    public static Node getLoopNode(Node head){
        if(head == null || head.next ==null || head.next.next ==null){
            return null;
        }

        Node n1 =head.next;
        Node n2 = head.next.next;

        while (n1 != n2){
            if(n2.next ==null || n2.next.next ==null){
                return null;
            }
            n2 = n2.next.next;
            n1 = n1.next;
        }
        n2 = head;
        while (n1 != n2){
            n1 = n1.next;
            n2 = n2.next;
        }
        return n1;
    }
//找出两个无环链表的一个相交节点,没相交返回null
    public static Node noLoop(Node head1 , Node head2){
        if(head1 ==null || head2 ==null){
            return null;
        }

        Node cur1 = head1;
        Node cur2 = head2;

        int n=  0;
        while (cur1.next != null){
            n++;
            cur1 = cur1.next;
        }

        while (cur2.next != null){
            n--;
            cur2 = cur2.next;
        }

        if(cur1 != cur2){
            return null;
        }

        //谁长谁为cur1,谁短谁为cur2
        cur1 = n > 0 ? head1 : head2;
        cur2 = cur1 == head1 ? head2 : head1;

        n = Math.abs(n);
        while ( n != 0){
            n--;
            cur1 = cur1.next;
        }

        while (cur1 != cur2){
            cur1 = cur1.next;
            cur2 = cur2.next;
        }

        return cur1;

    }
    
    //两个有环链表 , 返回第一个相交节点,如果不相交返回null
    public static Node bothLoop(Node head1, Node loop1 , Node head2 , Node loop2){
        Node cur1 = null;
        Node cur2 = null;
        
        if(loop1 == loop2) {
            cur1 = head1;
            cur2 = head2;

            int n = 0;
            while (cur1 != loop1) {
                n++;
                cur1 = cur1.next;
            }

            while (cur2 != loop2) {
                n--;
                cur2 = cur2.next;
            }

            cur1 = n > 0 ? head1 : head2;
            cur2 = cur1 == head1 ? head2 : head1;

            n = Math.abs(n);
            while (n != 0) {
                n--;
                cur1 = cur1.next;
            }

            while (cur1 != cur2) {
                cur1 = cur1.next;
                cur2 = cur2.next;
            }

            return cur1;
        }else{
            cur1 = loop1.next;
            while (cur1 != loop1){
                if(cur1 != loop2){
                    return loop1;
                }
                cur1 = cur1.next;
            }
            return null;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值