当前位置: 首页 > news >正文

141. 环形链表

问题描述

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。

示例 1:

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

d126accegy1g1uexpeoj0j20er04r0sr.jpg

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

解决方案

快慢指针法

想象一下,有两个速度不同的跑步者。如果他们在直路上行驶,快跑者将首先到达目的地。但是,如果它们在圆形跑道上跑步,那么快跑者如果继续跑步就会追上慢跑者。

这正是我们在链表中使用两个速度不同的指针时会遇到的情况:

  1. 如果没有环,快指针将停在链表的末尾。
  2. 如果有环,快指针最终将与慢指针相遇。

所以剩下的问题是:

这两个指针的适当速度应该是多少?

一个安全的选择是每次移动慢指针一步,而移动快指针两步。每一次迭代,快速指针将额外移动一步。如果环的长度为 M,经过 M 次迭代后,快指针肯定会多绕环一周,并赶上慢指针。

时间复杂度:O(n)

空间复杂度:O(1)

show me the code

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """

        quick_pointer = slow_pointer = head             # 创建两个指针,分别记录一个快的遍历指针,和一个慢的便利指针

        while quick_pointer and quick_pointer.next:     # 当快指针为None,或快指针的下个一对象为None,说明不是环形链表
            slow_pointer = slow_pointer.next            # 慢指针前进一步
            quick_pointer = quick_pointer.next.next     # 快指针前进两步
            if slow_pointer == quick_pointer:           # 假如快指针等于慢指针,说明为环形链表
                return True
        return False

hash表存贮法

顺序遍历链表所有节点,若出现重复访问则说明有环,否则说明无环。这里注意不能用list保存访问过的节点,查找太慢了;用dict保存还要考虑到键不能是对象,所以这里采取以对象的id作为键的做法。

时间复杂度:O(n)

空间复杂度:O(n)

show me the code

class Solution2(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        my_dict = {}                        # 创建一个字典来保存已经遍历过节点的内存地址
        while head and head.next:           # 当快指针为None,或快指针的下个一对象为None,说明不是环形链表
            if id(head) in my_dict:         # 假如当前节点在字典中则说明是环形链表
                return True
            else:
                my_dict[id(head)] = True    # 将当前节点加入到字典中

        return False

逆转链表检测法

倘若一个链表存在环,那么将这个链表反转,反转后的链表和原链表具有相同的head。证明起来比较麻烦,可以在纸上画一画来验证。

时间复杂度:O(n)

空间复杂度:O(n)

show me the code

class Solution3(object):
    def reverse_list(self, head):
        before = after = None
        while head:
            after = head.next # 保存当前节点的下一个节点
            head.next = before # 将当前节点的下一题个节点替换为当前节点的上一个节点
            before = head # 将上一个节点,往前移动,变为当前节点
            head = after # 当前节点向前移动
        return before # 返回反转完成后的头结点

    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if head and head.next and head == self.reverse_list(head): # 加入反转后的头结点与原先的头结点相同,则说明有环
            return True
        return False

转载于:https://www.cnblogs.com/huang-yc/p/10667642.html

相关文章:

  • 搞笑集合
  • 正式搬家到博客园
  • C# 和 c++的语法不同点
  • 我的新浪微博
  • 晴天霹雳。。傲盾把我的Linux格成了03系统了?之二
  • Log4j2入门
  • Notepad++插件安装和使用和打开大文件
  • 在SharePoint Server 2010中更改“我的网站”
  • 基数排序的理解和实现(Java)
  • P1962 斐波那契数列-题解(矩阵乘法扩展)
  • DotNetNuke模块开发(一)
  • LOJ104 普通平衡树
  • Airport Simulation (数据结构与算法 – 队列 / Queue 的应用)
  • 掌握 Dojo 工具包
  • js中用变量作为$()内id的值、动态获取id,及获取其下面的class元素
  • [deviceone开发]-do_Webview的基本示例
  • 【Amaple教程】5. 插件
  • Git的一些常用操作
  • Java基本数据类型之Number
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Laravel 中的一个后期静态绑定
  • Nodejs和JavaWeb协助开发
  • spark本地环境的搭建到运行第一个spark程序
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 京东美团研发面经
  • 跨域
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 算法-插入排序
  • 用 Swift 编写面向协议的视图
  • 栈实现走出迷宫(C++)
  • 回归生活:清理微信公众号
  • 我们雇佣了一只大猴子...
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​卜东波研究员:高观点下的少儿计算思维
  • #include<初见C语言之指针(5)>
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $ git push -u origin master 推送到远程库出错
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (剑指Offer)面试题34:丑数
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .NET Core Web APi类库如何内嵌运行?
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net MySql
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @EnableWebMvc介绍和使用详细demo
  • @private @protected @public
  • [2669]2-2 Time类的定义
  • [BZOJ4566][HAOI2016]找相同字符(SAM)
  • [C++][数据结构][算法]单链式结构的深拷贝