两条链表相交一些列问题

/**
 * 两条链表相交的一系列情况
 * 1、两条无环链表相交
 * 2、两条有环链表相交
 * 3、一条有环一条无环,肯定不相交
 */
public class LoopNode {

    //首先得判断这条链表有没有环
    public Node getLoopNode(Node head){
        //有环的话必须上三个节点以上,因此
        if (head == null || head.next == null || head.next.next == null){
            return null;
        }
        //链表有环情况,使用快慢指针
        Node s = head.next;
        Node f = head.next.next;
        //快指针一次走两步,慢指针一次走一步,走到相遇时停止
        while (s != f){
            if(f.next == null || f.next.next== null){
                return null;
            }
            f = f.next.next;
            s = s.next;
        }
        //走到相遇时,让快指针回到头结点
        f = head;
        while (s != f){
            s = s.next;
            f = f.next;
        }
        return s;
    }

    //如何判断两个无环链表是否相交,相交则返回第一个相交节点,不相交则返回 null
    public 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跑到链表长的头节点
        cur1 = n > 0 ? head1 : head2;
        //根据上面cur1的选择,cur2选择另外一条链表的头节点
        cur2 = cur1 == head1 ? head2 : head1;
        n = Math.abs(n);
        //cur1跑到和cur2一样的位置
        while (n != 0){
            n--;
            cur1 = cur1.next;
        }
        //开始同时跑
        while (cur1 != cur2){
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        return cur1;
    }
    //判断两个有环链表相交
    private Node bothLoop(Node head1, Node node1, Node head2, Node node2) {
        Node cur1 = null;
        Node cur2 = null;
        //跟两条无环链表相交一样
        if(node1 == node2){
            cur1 = head1;
            cur2 = head2;
            int n = 0;
            while (cur1 != node1) {
                n++;
                cur1 = cur1.next;
            }
            while (cur2 != node2) {
                n--;
                cur2 = cur2.next;
            }
            //cur1跑到链表长的头节点
            cur1 = n > 0 ? head1 : head2;
            //根据上面cur1的选择,cur2选择另外一条链表的头节点
            cur2 = cur1 == head1 ? head2 : head1;
            n = Math.abs(n);
            //cur1跑到和cur2一样的位置
            while (n != 0){
                n--;
                cur1 = cur1.next;
            }
            //开始同时跑
            while (cur1 != cur2){
                cur1 = cur1.next;
                cur2 = cur2.next;
            }
            return cur1;
        }else {
            cur1 = node1.next;
            while (cur1 != node1){
                if(cur1 == node2){
                    return node1;
                }
                cur1 = cur1.next;
            }
            return null;
        }
    }

    //两个链表相交
    public Node getIntersectNode(Node head1,Node head2){
        if (head1 == null || head2 == null){
            return null;
        }
        //首先各自判断两条链表是否有环
        Node node1 = getLoopNode(head1);
        Node node2 = getLoopNode(head2);
        //两个无环链表相交
        if(node1 == null && node2 == null){
            return noLoop(head1,head2);
        }
        if(node1 != null && node2 != null){
            return bothLoop(head1,node1,head2,node2);
        }
        return null;
    }


    public static void main(String[] args) {
        LoopNode loopNode = new LoopNode();
        //有环链表head1
        Node head1 = new Node(3);
        head1.next = new Node(2);
        head1.next.next = new Node(0);
        head1.next.next.next = new Node(-4);
        head1.next.next.next.next = new Node(6);
        head1.next.next.next.next.next = head1.next;
        Node head2 = new Node(1);
        head2.next = new Node(6);
        head2.next.next = head1.next;
        head2.next.next.next = head1.next.next;
        head2.next.next.next.next = head1.next.next.next;
        head2.next.next.next.next.next = head2.next;

        /*head1.next.next.next.next = head1.next;
        LoopNode loopNode = new LoopNode();
        Node node = loopNode.getLoopNode(head1);
        System.out.println(node.value);*/

        /*Node node = loopNode.noLoop(head1, head2);
        System.out.println(node.value);*/

        Node node = loopNode.getIntersectNode(head1, head2);

        System.out.println(node.value);

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值