算法一招鲜:环形链表之双指针

双指针技巧还可以分为两类,一类是「快慢指针」,另一类是「左右指针」。 前者解决主要解决链表中的问题,比如典型的判定链表中是否包含环;后者主要解决数组(或者字符串)中的问题,比如二分查找。

环形链表

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

题目分析

  • JS特殊解法

相信对于 JS 中的 JSON.stringify() 方法大家都用过,主要用于将 JS 对象 转换为 JSON 字符串。基本使用如下:

var car = {
    name'环形链表',
    age123,
}
var str = JSON.stringify(car);
console.log(str)
// {"name":"环形链表","age":123}

大家想一下,如果是自己实现这样的一个函数,我们需要处理什么样的特殊情况?对,就是循环引用。因为对于循环引用,我们很难通过 JSON 的结构将其进行展示!

比如下面:

var ls = {
    name'李四',
    age27
}
var zs = {
    name'张三',
    age12
}
ls.father = zs;
zs.father = ls;
console.log(zs)
console.log(JSON.stringify(zs))

所以我们可以通过 JSON.stringify() 的特性进行求解:

var hasCycle = function(head{
    try{
        JSON.stringify(head)
    }catch(e){
        return true
    }
    return false
};

当然,这种解法并不是建议的标准题解!在此列出是为了拓宽思维!(大家如有兴趣,可以自己去看下JSON.stringify 内部的实现,是如何检测循环引用的。)

  • 双指针解法

也是本题标准解法!

思路来源:先想象一下,两名运动员以不同速度在跑道上进行跑步会怎么样?

相遇!

好了,这道题你会了。

解题方法:通过使用具有 不同速度 的快、慢两个指针遍历链表,空间复杂度可以被降低至 O(1)。慢指针每次移动一步,而快指针每次移动两步。

假设链表为

其步骤如下:

分析完毕,直接上代码:

var ls = {
    name'李四',
    age3
}
var zs = {
    name'张三',
    age2
}
var ww = {
    name'王五',
    age4
}
var zl = {
    name'赵六',
    age0
}
ls.next = zs;
zs.next = ww;
ww.next = zl;
zl.next = ls;

console.log(zs);

function hasCycle(ListNode{
    if (!ListNode) return;
    let fast = ListNode.next;   // 快指针图1

    while (fast && ListNode && fast.next) {
        if (fast == ListNode) {
            return true;
        }
        ListNode = ListNode.next;
        fast = fast.next.next
    }
    return false;
}


console.log(hasCycle(zs));

zl.next = {};

console.log(hasCycle(zs));

这里我们要特别说明一下,为什么慢指针的步长设置为 1 ,而快指针步长设置为 2 。

首先,慢指针步长为 1,很容易理解,因为我们需要让慢指针步行至每一个元素。而快指针步长为 2 ,通俗点可以理解为他们的相对速度只差 1,快的只能一个一个格子的去追慢的,必然在一个格子相遇。

如果没看懂,我们来分析:在快的快追上慢的时,他们之间一定是只差 1 个或者 2 个格子。如果落后 1 个,那么下一次就追上了。如果落后 2 个,那么下一次就落后 1 个,再下一次就能追上!

如下图:

所以我们的快指针的步长可以设置为 2 。

原文参考

  • 小浩算法:https://www.geekxh.com/1.1.%E9%93%BE%E8%A1%A8%E7%B3%BB%E5%88%97/103.html


本文分享自微信公众号 - JavaScript忍者秘籍(js-obok)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

微信关注我们

原文链接:https://my.oschina.net/u/3024426/blog/4692596

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

Apache Tomcat7、8、9(Java Web服务器)

Apache Tomcat7、8、9(Java Web服务器)

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Eclipse(集成开发环境)

Eclipse(集成开发环境)

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。