【切图仔的算法修炼之旅】LeetCode141:判断链表是否有环

简介: 【切图仔的算法修炼之旅】LeetCode141:判断链表是否有环

一、题目描述


给你一个链表的头节点 head ,判断链表中是否有环。


如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。


如果链表中存在环 ,则返回 true 。 否则,返回 false 。


示例1:


image.png


输入: head = [3,2,0,-4], pos = 1
输出: true
解释: 链表中有一个环,其尾部连接到第二个节点。
复制代码


示例2:


image.png


输入: head = [1,2], pos = 0
输出: true
解释: 链表中有一个环,其尾部连接到第一个节点。
复制代码


提示:


  • 链表中节点的数目范围是 [0, 104]
  • -105 <= Node.val <= 105
  • pos-1 或者链表中的一个 有效索引


二、思路分析


这一道题目还是比较考验你的思维能力的,有三种做法


  1. 第一种做法就是暴力解法,一直循环next,看是否能结束循环,当然这种解法性能一定很差,我们肯定是不推荐的。
  2. 第二种做法就是使用Set数据结构,遍历到的每个节点将他存起来,Set数据结构的特性就是一组唯一值的集合,关于它的更多的信息可以查看MDN-JavaScript标准内置对象-Set,wow,MDN居然有了新的文档!!!。该做法的时间复杂度是O(n * 1) = O(n)
  3. 第三种做法就是龟兔赛跑的解法,也就是使用快慢指针,快指针走2步,慢指针走一步,如果链表没有环,那么它们一定不会走到同一节点,如果链表有环,那么它们将会一定相遇,当然这种解法可能比较反人类,比较难想到。该做法的时间复杂度也是O(n)


三、AC代码


  1. Set数据结构解法


const hasCycle = function(head) {
    const visited = new Set()
    while(head) {
        if(visited.has(head)) {
            return true
        }
        visited.add(head)
        head = head.next
    }
    return false
};
复制代码


  1. 龟兔赛跑解法


var hasCycle = function(head) {
   let p1 = head, p2 = head
   while (p1 && p2.next && p2.next.next) {
     p1 = p1.next
     p2 = p2.next.next
     if (p1 === p2) {
       return true
     }
   }
   return false
};
复制代码


四、总结


这题在思维上还是有一点的,我们推荐使用后面两种解法,Set解法是比较中规中举的解法,龟兔赛跑解法比较反人类,可能你很难想到,它相比于Set解法更加节省内存,因为你不用将每个节点存起来,如果你能在面试的时候能想到这三种解法,那你一定会在面试官面前眼前一亮。

相关文章
|
4天前
|
算法
LeetCode第24题两两交换链表中的节点
这篇文章介绍了LeetCode第24题"两两交换链表中的节点"的解题方法,通过使用虚拟节点和前驱节点技巧,实现了链表中相邻节点的交换。
LeetCode第24题两两交换链表中的节点
|
3天前
|
存储 算法
LeetCode第86题分隔链表
文章介绍了LeetCode第86题"分隔链表"的解法,通过创建两个新链表分别存储小于和大于等于给定值x的节点,然后合并这两个链表来解决问题,提供了一种简单易懂且操作原链表的解决方案。
LeetCode第86题分隔链表
|
3天前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
4天前
|
算法
LeetCode第23题合并 K 个升序链表
这篇文章介绍了LeetCode第23题"合并K个升序链表"的解题方法,使用分而治之的思想,通过递归合并链表的方式解决了这个难题。
LeetCode第23题合并 K 个升序链表
|
3天前
|
算法
LeetCode第92题反转链表 II
文章分享了LeetCode第92题"反转链表 II"的解法,通过使用四个指针来记录和更新反转链表段的头部、尾部以及前一个和后一个节点,提供了一种清晰且易于理解的解决方案。
LeetCode第92题反转链表 II
|
4天前
|
算法
LeetCode第21题合并两个有序链表
该文章介绍了 LeetCode 第 21 题合并两个有序链表的解法,通过创建新链表,依次比较两个链表的头节点值,将较小的值插入新链表,直至其中一个链表遍历完,再将另一个链表剩余部分接到新链表后面,实现合并。
LeetCode第21题合并两个有序链表
|
3天前
|
算法
【数据结构与算法】共享双向链表
【数据结构与算法】共享双向链表
4 0
|
3天前
|
算法
【数据结构与算法】双向链表
【数据结构与算法】双向链表
4 0
|
3天前
|
算法
【数据结构与算法】循环链表
【数据结构与算法】循环链表
4 0
|
3天前
|
存储 算法
【数据结构与算法】链表
【数据结构与算法】链表
4 0