两个单链表相交的一系列问题【Java实现】

问题一:

如何判断一个单链表是否有环,如果有,则返回第一个进入环的节点,没有则返回null。

思路:

快慢指针

(1)定义快指针fast,满指针slow,开始时候,fast和slow都指向链表的头节点,slow每次走一步,fast每次走两步。

(2)如果fast到了终点,说明无环,返回null。

(3)如果有环,fast和slow一定会在某个位置相遇,此时让fast指针重新回到头节点,然后fast和slow同时一步一步移动,再次相遇的点就是入环节点。

代码实现:

    public Node getLoopNode(Node head) {
        if (head == null || head.next == null || head.next.next == null) {
            return null;
        }
        Node slow = head.next;
        Node fast = head.next.next;
        while (slow != fast) {
            //如果走到空 说明无环,直接返回null
            if (fast.next == null || fast.next.next == null) {
                return null;
            }
            //慢指针走一步 快指针走两步
            slow = slow.next;
            fast = fast.next.next;
        }
        //此时slow和fast相遇,让fast回到头节点
        fast = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }


问题二:

如何判断两个无环链表是否相交,相交则返回第一个相交节点,不相交则返回null。

思路:

(1)链表1从头节点开始走到最后一个节点,统计链表1的长度为len1,记录最后一个节点end1。

(2)链表2从头节点开始走到最后一个节点,统计链表2的长度为len2,记录最后一个节点end2。

(3)如果 end1 != end2,则说明两个链表不相交,返回null,如果end1 == end2,说明两个链表相交。

(4)如果链表1较长,链表1就先走len1-len2步,同理链表2较长,链表2就先走len2-len1步。然后一起走,两个链表第一次走到的节点就是相交节点。

    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.next = cur2;
        }
        //判断此时cur1和cur2是否相等
        if (cur1 != cur2) {
            return null;
        }
        //n大于0说明链表1更长  只要记住 cur1永远是指的更长的链表的头节点
        //n>0时,cur1是head1 cur2是head2
        //n<0时,cur1是head2 cur2是head1
        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;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小印z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值