【LeetCode 力扣 142】环形链表Ⅱ, 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

学习目标:

目标:熟练运用Java所学知识


学习内容:

本文内容:使用Java实现:环形链表Ⅱ


题目描述:

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

示例 1:
在这里插入图片描述

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

在这里插入图片描述

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

在这里插入图片描述

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

解题步骤:

  • 第一步:排除空链表和只有一个节点的情况
        //排除空链表和只有一个节点的情况
        if(head==null||head.next==null){
    
    
            return null;
        }
  • 第二步:判断链表是否带环
//通过循环判断链表是否带环
        while(fast!=null&&fast.next!=null){
    
    
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
    
    
                //表示链表带环,结束循环
                break;
            }
        }
  • 第三步:如果链表没有环,则返回空
   //判断上述while循环结束的原因,只有两个原因
   //第一个原因:如果快指针走到了链表结尾,则返回null
   if(fast==null||fast.next==null){
    
    
       return null;
   }
  • 第四步:链表带环,找到链表入环的第一个结点

如果链表带环,则 快慢指针相遇的结点 和 链表头结点 距离链表入环的第一个结点是相同的所以只需要同步遍历,直到第一次相遇既为链表入环的第一个结点

  //第二个原因:链表带环
  //如果链表带环,则 快慢指针相遇的结点 和 链表头结点 距离链表入环的第一个结点是相同的
  //所以只需要同步遍历,直到第一次相遇既为链表入环的第一个结点
  while(cur!=fast){
    
    
      cur=cur.next;
      fast=fast.next;
  }
  return fast;

实现代码:

    public static ListNode detectCycle(ListNode head) {
    
    
        //排除空链表和只有一个节点的情况
        if(head==null||head.next==null){
    
    
            return null;
        }

        ListNode slow=head;//慢指针
        ListNode fast=head;//快指针
        ListNode cur=head;
        //通过循环判断链表是否带环
        while(fast!=null&&fast.next!=null){
    
    
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
    
    
                //表示链表带环,结束循环
                break;
            }
        }
        //判断上述while循环结束的原因,只有两个原因
        //第一个原因:如果快指针走到了链表结尾,则返回null
        if(fast==null||fast.next==null){
    
    
            return null;
        }
        //第二个原因:链表带环
        //如果链表带环,则 快慢指针相遇的结点 和 链表头结点 距离链表入环的第一个结点是相同的
        //所以只需要同步遍历,直到第一次相遇既为链表入环的第一个结点
        while(cur!=fast){
    
    
            cur=cur.next;
            fast=fast.next;
        }
        return fast;
    }

猜你喜欢

转载自blog.csdn.net/zhangxxin/article/details/114589759