Leetcode [141, 142] Linked List Cycle,java解法

Creo报错代码-9?手把手教你重新生成许可证文件(基于Creo 10.0) 本文详细解析Creo报错代码-9的成因及解决方案,重点介绍如何重新生成许可证文件以应对网络环境变化导致的验证失败。通过分步指南和高级技巧,帮助用户有效管理多网络环境下的Creo许可证问题,提升工作效率。 阅读详情

141 Linked List Cycle 

Given a linked list, determine if it has a cycle in it.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the second node.

Example 2:

Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.

Approach #1 Hash Set

public boolean hasCycle(ListNode head) {
    Set<ListNode> nodesSeen = new HashSet<>();
    while (head != null) {
        if (nodesSeen.contains(head)) {
            return true;
        } else {
            nodesSeen.add(head);
        }
        head = head.next;
    }
    return false;
}

Complexity analysis

  • Time complexity : O(n). We visit each of the nn elements in the list at most once. Adding a node to the hash table costs only O(1)time.

  • Space complexity: O(n). The space depends on the number of elements added to the hash table, which contains at most nn elements. 

Approach #2 Two Pointers

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null) return false;
        // unlike int index in arrays, we now use Listnode as pointers
        ListNode slow = head;
        ListNode fast = head.next;
        while (fast.next != null && fast.next.next != null) {
            if (slow == fast) return true;
            
            slow = slow.next;
            fast = fast.next.next;
        }
        
        return false; 
    }
}

Complexity analysis

  • Time complexity : O(n). Let us denote nn as the total number of nodes in the linked list. To analyze its time complexity, we consider the following two cases separately.

    • List has no cycle:
      The fast pointer reaches the end first and the run time depends on the list's length, which is O(n)O(n).

    • List has a cycle:
      We break down the movement of the slow pointer into two steps, the non-cyclic part and the cyclic part:

      1. The slow pointer takes "non-cyclic length" steps to enter the cycle. At this point, the fast pointer has already reached the cycle. \text{Number of iterations} = \text{non-cyclic length} = NNumber of iterations=non-cyclic length=N

      2. Both pointers are now in the cycle. Consider two runners running in a cycle - the fast runner moves 2 steps while the slow runner moves 1 steps at a time. Since the speed difference is 1, it takes \dfrac{\text{distance between the 2 runners}}{\text{difference of speed}}difference of speeddistance between the 2 runners​ loops for the fast runner to catch up with the slow runner. As the distance is at most "\text{cyclic length K}cyclic length K" and the speed difference is 1, we conclude that
        \text{Number of iterations} = \text{almost}Number of iterations=almost "\text{cyclic length K}cyclic length K".

    Therefore, the worst case time complexity is O(N+K), which is O(n)O(n).

  • Space complexity : O(1). We only use two nodes (slow and fast) so the space complexity is O(1)

 

142. Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note: Do not modify the linked list.

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

Example 2:

Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

Approach #1 Hash Table

public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> visited = new HashSet<ListNode>();

        ListNode node = head;
        while (node != null) {
            if (visited.contains(node)) {
                return node;
            }
            visited.add(node);
            node = node.next;
        }

        return null;
    }
}

Complexity Analysis

  • Time complexity : O(n)O(n)

    For both cyclic and acyclic inputs, the algorithm must visit each node exactly once. This is transparently obvious for acyclic lists because the nnth node points to null, causing the loop to terminate. For cyclic lists, the if condition will cause the function to return after visiting the nnth node, as it points to some node that is already in visited. In both cases, the number of nodes visited is exactly nn, so the runtime is linear in the number of nodes.

  • Space complexity : O(n)O(n)

    For both cyclic and acyclic inputs, we will need to insert each node into the Set once. The only difference between the two cases is whether we discover that the "last" node points to null or a previously-visited node. Therefore, because the Set will contain nn distinct nodes, the memory footprint is linear in the number of nodes.

Approach #2 Floyd's Tortoise and Hare

public class Solution {
    private ListNode getIntersect(ListNode head) {
        ListNode tortoise = head;
        ListNode hare = head;

        // A fast pointer will either loop around a cycle and meet the slow
        // pointer or reach the `null` at the end of a non-cyclic list.
        while (hare != null && hare.next != null) {
            tortoise = tortoise.next;
            hare = hare.next.next;
            if (tortoise == hare) {
                return tortoise;
            }
        }

        return null;
}

    public ListNode detectCycle(ListNode head) {
        if (head == null) {
            return null;
        }

        // If there is a cycle, the fast/slow pointers will intersect at some
        // node. Otherwise, there is no cycle, so we cannot find an entrance to
        // a cycle.
        ListNode intersect = getIntersect(head);
        if (intersect == null) {
            return null;
        }

        // To find the entrance to the cycle, we have two pointers traverse at
        // the same speed -- one from the front of the list, and the other from
        // the point of intersection.
        ListNode ptr1 = head;
        ListNode ptr2 = intersect;
        while (ptr1 != ptr2) {
            ptr1 = ptr1.next;
            ptr2 = ptr2.next;
        }

        return ptr1;
    }
}

Complexity Analysis

  • Time complexity : O(n)O(n)

    For cyclic lists, hare and tortoise will point to the same node after F+C-hF+C−h iterations, as demonstrated in the proof of correctness. F+C-h \leq F+C = nF+C−h≤F+C=n, so phase 1 runs in O(n) time. Phase 2 runs for F < nF<n iterations, so it also runs in O(n) time.

    For acyclic lists, hare will reach the end of the list in roughly \dfrac{n}{2}2n​iterations, causing the function to return before phase 2. Therefore, regardless of which category of list the algorithm receives, it runs in time linearly proportional to the number of nodes.

  • Space complexity : O(1)

    Floyd's Tortoise and Hare algorithm allocates only pointers, so it runs with constant overall memory usage.

三、 关于链表Linked List

设计一个单链表:

/**
 * A singly linked list with a left sentinel node.
 */
class MyLinkedList {

	/** A very simple node class. */
	private static class Node {
		int val;
		Node next;
	}

	// Predecessor of the first element
	private Node headPred;
	// Predecessor of the tail
	private Node tailPred;
	private int length;

	/** Initialize your data structure here. */
	public MyLinkedList() {
		headPred = new Node();
		tailPred = headPred;
		length = 0;
	}

	/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
	public int get(int index) {
		if ((index < 0) || (index >= length)) {
			return -1;
		}
		return findPred(index).next.val;
	}

	/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
	public void addAtHead(int val) {
		if (length == 0) {
			addAtTail(val);
		} else {
			addAfter(headPred, val);
		}
	}

	/** Append a node of value val to the last element of the linked list. */
	public void addAtTail(int val) {
		addAfter(tailPred, val);
		tailPred = tailPred.next;
	}

	/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
	public void addAtIndex(int index, int val) {
		if (index < 0) {
			addAtHead(val);
		} else if (index == length) {
			addAtTail(val);
		} else if ((index >= 0) && (index < length)) {
			addAfter(findPred(index), val);
		}
	}

	/** Delete the index-th node in the linked list, if the index is valid. */
	public void deleteAtIndex(int index) {
		if ((index >= 0) && (index < length)) {
			Node pred = findPred(index);
			if (index == length - 1) { // Remove last element
				// Move tail to the left
				tailPred = pred;
			}
			pred.next = pred.next.next;
			--length;
		}
	}

	/** Return the predecessor of the index-th node. */
	private Node findPred(int index) {
		Node pred = headPred;
		for (int i = 0; i < index; ++i) {
			pred = pred.next;
		}
		return pred;
	}

	/** Add an element after the given node. */
	private void addAfter(Node pred, int val) {
		Node node = new Node();
		node.val = val;
		node.next = pred.next;
		pred.next = node;
		++length;
	}
}

 

十二种嵌入式通信协议 嵌入式通信协议选型核心要点解析 在嵌入式系统开发中,通信协议选型直接影响项目成败。本文系统梳理了12种主流协议,从三个维度提供选型指南: 板级通信协议: I²C:双线制,适合传感器连接(温湿度、RTC等) SPI:高速全双工,适用于Flash存储、TFT屏等 UART:异步串行,常用于调试日志输出 总线通信协议: CAN:汽车电子首选,支持多主节点和硬件仲裁 LIN:低成本单线方案,适用于车窗控制等场景 RS485:工业自动化主力,最长传输距离1200米 Modbus:工业领域通用协议,支持RTU/TCP格 阅读详情

相关推荐

告别时钟树平衡噩梦:在Innovus中巧妙设置stop/ignore pin来优化分段时钟网络

本文深入探讨了在Innovus工具中利用stop/ignore pin优化分段时钟树网络的高阶技巧。针对数字IC后端设计中的时钟树平衡难题,详细解析了特殊引脚属性的战略应用场景和配置方法,帮助工程师有效解决SoC设计中复杂的时钟结构问题,显著提升时序收敛效率。

weixin_30836759的博客 286

LeetCode—linked-list-cycle(检测是否有环)—Java

题目描述:Given a linked list, determine if it has a cycle in it.Follow up:Can you solve it without using extra space?思路解析:这个只需要快慢指针的方法就可以检测是否有环。代码:/** * Definition for singly-linked list. * class ListNo...

Lynn_Baby的博客 394

复用浏览器之跳过扫码登录

复用浏览器 1、通过命令启动浏览器:chrome --remote-debugging-port=9222(前提是退出所有的chrome浏览器) 2、启动浏览器之后,在地址栏输入127.0.01:9222,成功复用如下图所示:

qq_43911915的博客 2033

LeetCode----Linked List Cycle

Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space? 分析: 判断一个链表是否含有环。 使用弗洛伊德循环检测法。时间复杂度为O(n)。 算法详解如下:

whiterbear的专栏 875

Hand-Eye 标定误差分析:从理论到 C++ 实现

本文深入探讨了机器人手眼标定中的核心环节——误差分析。文章从AX=XB方程的理论残差出发,详细解析了旋转与平移误差的数学定义与物理意义,并提供了一个工业级的C++实现代码,用于计算重投影误差。通过误差分析,工程师可以量化标定精度,诊断问题根源,从而确保视觉引导机器人系统在实际应用中的可靠性与精确性。

c7d8e的博客 695

传感器:MQ-5燃气模块测量燃气值(底部附代码)

本篇文章介绍使用MQ-5燃气模块测量燃气值,CPU还是选择单片机,MQ-5主要使用的技术为ADC,燃气对于单片机来说是模拟信号,需要转换为数字信号,再经过相关计算公式将燃气模拟值转换成对应的燃气数值,便于人们方便查看。例如家庭使用燃气模块测量燃气值,如果燃气值超过一定的范围,可以外设一个报警装置,保证家庭的生命安全。(1)ADC(analog to digital converter)即模数转换器,它可以将模拟信号转换为数字信号。按照其转换原理主要分为逐次逼近型、双积分型、电压频率转换型三种。STM32F1

Mr_zhang1911116的博客 1万+

Linked List Cycle(判断链表是否有环)-python

Given a linked list, determine if it has a cycle in it.解答:定义两个指针分别从链表头部开始,一个指针每次走一步,另一个指针每次走两步,若两个指针所指的值相等,则说明有环,否则没环;要注意指针所指之处是否为空class Solution(object):    def hasCycle(self, head):        """      ...

qq_22179091的博客 1002

IGBT模块封装中的银烧结技术:为什么特斯拉和比亚迪都在用这种黑科技?

本文深入解析了IGBT模块封装中的银烧结技术,揭示了其作为功率半导体封装工艺关键升级的原因。该技术通过低温烧结形成高熔点、高导热导电的银连接层,显著提升了模块的功率循环寿命、散热能力和高温工作稳定性,这正是特斯拉、比亚迪等行业巨头采用此项黑科技以释放电动汽车电驱系统极致性能的核心所在。

yhn4567890的博客 833

LeetCode 之 linked-list-cycle【检测链表中是否有环】

题目: Given a linked list, determine if it has a cycle in it.   Follow up:   Can you solve it without using extra space?   思路一:要达到的目的,检测链表中是否有环,首先第一个思路可以是遍历整个链表,并标记访问过的节点,如果重复访问了某个节点,说明该链表中有环。该思路实现简单,...

李滚滚的博客 557

【教程4>第6章>第15节】 基于I+jQ复数信号的LS信道估计和均衡实现1——matlab仿真分析,QPSK为例

在基于QPSK调制的通信系统中,LS信道估计和均衡是用于补偿信道失真、提高信号传输质量的重要技术。以下将详细介绍基于I+jQ复数信号的 LS 信道估计和均衡的实现原理与过程。可以看到,通过线性插值之后,QPSK信号的星座图可以模糊的看到四个星座点(图2),通过非线性插值之后,可以清晰的看到QPSK的四个星座点(图3)。可以看到,信道均衡显著提高了通信系统的可靠性和有效性。

FPGA/MATLAB学习教程/源码/项目合作开发 657

YOLOv13添加OREPA模块 准确率提升10.56个点,map提升11.87个点。小目标轻量化

本文提出了一种新的OREPA(Optimal Recursive Edge-Preserving Attention)模块,通过结合递归和边缘保留注意力机制,显著提升了目标检测模型的性能。实验结果表明,添加OREPA模块后,准确率提升了10.56个百分点,mAP提升了11.87个百分点。OREPA模块包含三个核心组件:OREPA1处理特征图并保留边缘信息,Bottleneck_OREPA作为瓶颈模块降低计算量,OREPA类通过堆叠多个Bottleneck_OREPA增强网络表达能力。文章详细介绍了如何将OR

FJN110的博客 2761

LeetCode Top 100 Liked Questions 141. Linked List Cycle (Java版; Easy)

welcome to my blog LeetCode Top 100 Liked Questions 141. Linked List Cycle (Java版; Easy) 题目描述 Given a linked list, determine if it has a cycle in it. To represent a cycle in the given linked list, we...

littlehaes的博客 179

13、数据来源介绍与操作指南

本文详细介绍了多种数据源的特点、操作步骤及适用场景,包括元数据数据源、MongoDB数据源、Pentaho Data Integration数据源、OLAP数据源、Pentaho分析数据源和OLAP4J数据源。通过流程图和表格对比,帮助用户理解不同数据源的选择与使用方法,并提供了实际应用案例和注意事项,旨在提升数据获取与分析效率,支持高效报告生成。

ik678901234的博客 148

(Leetcode 142)Linked List Cycle (II) (快慢指针详解)

Leetcode141题和142题很相似,都涉及到了快慢指针的算法。快慢指针就是设置两个指针,一个快指针,一个慢指针来达到解题的目的。下面分为以下几个模块来讲解: 解第141题解第142题为什么快指针一定要设置为慢指针的2倍快慢指针的拓展应用 一、Leetcode 141题 题目为:Linked List Cycle Given a linked list, determi

willduan的博客 1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

(Leetcode 142)Linked List Cycle (II) (快慢指针详解)

Leetcode141题和142题很相似,都涉及到了快慢指针的算法。快慢指针就是设置两个指针,一个快指针,一个慢指针来达到解题的目的。下面分为以下几个模块来讲解: 解第141题 解第142题 为什么快指针一定要设置为慢指针的2倍 快慢指针的拓展应用 一、Leetcode 141题 题目为:Linked List Cycle Given a linked list, determine i...

zhunode的探索 330

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

LeetCode-141.142. Linked List Cycle (JAVA)链表找环

LeetCode-141.142. Linked List Cycle (JAVA)链表找环

mine_song的博客 936

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

LeetCode 141 Linked List Cycle 142 Linked List Cycle II

问题描述: 解答: public class Solution { public boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return false; } ListNode slow=head;...

susuxuezhang的博客 271

leetcode 141. Linked List Cycle 快慢指针

题意 返回是否有环 解1 // 全部存下来 // Runtime: 3 ms, faster than 19.84% of Java online submissions for Linked List Cycle. //Memory Usage: 39.2 MB, less than 16.56% of Java online submissions for Linked List Cycle. public boolean hasCycle(ListNode head)

1 141

leetcode 142. Linked List Cycle II 龟兔赛跑(循环指针)

上一题 题意 如果有环,找出环第一个出现的节点,如果没有,返回null。 解1 空间O(N) // Runtime: 3 ms, faster than 23.27% of Java online submissions for Linked List Cycle II. //Memory Usage: 39.7 MB, less than 5.94% of Java online submissions for Linked List Cycle II. public ListNo

1 180

LeetCode 142. 环形链表 II(Linked List Cycle II)

142. 环形链表 II 142. Linked List Cycle II 题目描述 给定一个链表,返回链表开始入环的第一个节点。如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。 说明: 不允许修改给定的链表。 LeetCode142. Linked List Cycl...

weixin_30788731的博客 111

【leetcode】142. Linked List Cycle II

第142是第141的一个升级版, Given a linked list, determine if it has a cycle in it. 141要求的是查出是否存在有一个链表的循环; Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

SherryWay的博客 263

LeetCode 142. Linked List Cycle II(快慢指针)

Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To represent a cycle in the given linked list, we use an integer pos which represen...

da_kao_la的博客 275

C语言快慢指针,【算法分析】如何理解快慢指针?判断linked list中是否有环、找到环的起始节点位置。以Leetcode 141. Linked List Cycle, 142. Linked L...

引入快慢指针经常用于链表(linked list)中环(Cycle)相关的问题。LeetCode中对应题目分别是:简介快指针(fast pointer)和慢指针(slow pointer)都从链表的head出发。slow pointer每次移动一格,而快指针每次移动两格。如果快慢指针能相遇,则证明链表中有环;否则如果走到头了依然没有相遇,则没有环。快慢指针的具体代码(C++, Python, Ja...

weixin_36403165的博客 263

【LeetCode-面试算法经典-Java实现】【142-Linked List Cycle II(单链表中有环II)】

【142-Linked List Cycle II(单链表中有环II)】【LeetCode-面试算法经典-Java实现】【所有题目目录索引】原题  Given a linked list, return the node where the cycle begins. If there is no cycle, return null.   Follow up:   Can you solve

https://github.com/Wang-Jun-Chao 4410

【LeetCode】142. Linked List Cycle II

Difficulty:medium More:【目录】LeetCode Java实现 Description Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull. Note:Do not modify the linked list. Follow...

weixin_30677073的博客 121

LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】

目录 一,题目描述 英文描述 中文描述 二,解题思路 三,AC代码 C++ Java 四,解题过程 第一博 一,题目描述 英文描述 Given a linked list, return the node where the cycle begins. If there is no cycle, return null. There is a cycle in a linked list if there is some node in the list that can be

&再见萤火虫&的博客 247
上一篇: Leetcode[217, 136, 349, 202] HashTable 小专题 1 HashSet
下一篇: 亚麻 OA 2019 题目
YuanTheCoder
博客等级 码龄9年 2粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值