2021-06-17环形链表!!

leetcode每日一题之环形链表!!

题目链接:https://leetcode-cn.com/problems/linked-list-cycle-ii/submissions/

题目描述:

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

例:
img

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

解法1:

利用Set存储节点,遍历,当出现重复说明有环

代码:比较简单,因此无注释

public ListNode detectCycle(ListNode head) {
        Set<ListNode> nodeSet = new HashSet<>();
        while (head != null) {
            if (nodeSet.contains(head)) {
                return head;
            }
            nodeSet.add(head);
            head = head.next;
        }
        return null;
    }

解法2:官方题解,快慢指针

具体分析看题解:https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/huan-xing-lian-biao-ii-by-leetcode-solution/

package com.tao.linklist;
/**
 * @Classname DetectCycle
 * @Description TODO
 * @Date 2021/6/17 13:22
 * @Author Anonymous
 */
@SuppressWarnings("all")
public class DetectCycle {
    public static void main(String[] args) {
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        node1.next = node2;
        node2.next = node1;
        ListNode node = detectCycle(node1);
        System.out.println(node.val);
    }

    public static ListNode detectCycle(ListNode head) {
        // 链表本身不能为空 或者只有一个节点 也是无环的
        if (head == null || head.next == null) {
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        while (true) {
            // 没有环时 fast会先走到链表尾部
            if (fast == null || fast.next == null) {
                return null;
            }
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) break;
        }
        // 第一次相遇后,让fast重新指向头结点head,slow保持不变。
        // fast和slow按照相同速度移动,第二次相遇后,此节点即为入口节点。
        fast=head;
        while(fast!=slow){
            fast=fast.next;
            slow=slow.next;
        }
        //相遇点就是入口
        return slow;
    }
}

拓展://可以求环的长度,当第二次相遇之后,也就是到达环的入口之后,开始遍历,存储到Set集合,当下次再出现环入口节点停止,就得到了环的长度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值