博客
关于我
环形数组循环
阅读量:405 次
发布时间:2019-03-06

本文共 1909 字,大约阅读时间需要 6 分钟。

环形数组循环

给定一个含有正整数和负整数的环形数组nums,如果某个索引中的数k为正数,则向前移动 k个索引,相反如果是负数-k,则向后移动k个索引。因为数组是环形的,所以可以假设最后一个元素的下一个元素是第一个元素,而第一个元素的前一个元素是最后一个元素,确定nums中是否存在循环或周期。循环必须在相同的索引处开始和结束并且循环长度>1。此外,一个循环中的所有运动都必须沿着同一方向进行,换句话说,一个循环中不能同时包括向前的运动和向后的运动。

示例

输入:[2,-1,1,2,2]输出:true解释:存在循环,按索引 0 -> 2 -> 3 -> 0 。循环长度为 3 。
输入:[-1,2]输出:false解释:按索引 1 -> 1 -> 1 ... 的运动无法构成循环,因为循环的长度为 1 。根据定义,循环的长度必须大于 1 。
输入:[-2,1,-1,-2,-2]输出:false解释:按索引 1 -> 2 -> 1 -> ... 的运动无法构成循环,因为按索引 1 -> 2 的运动是向前的运动,而按索引 2 -> 1 的运动是向后的运动。一个循环中的所有运动都必须沿着同一方向进行。

题解

/** * @param {number[]} nums * @return {boolean} */var circularArrayLoop = function(nums) {    var n = nums.length;    var getNext = x => {        var nextIndex = (x+nums[x])%n;        return nextIndex >= 0 ? nextIndex : nextIndex+n;    };    for(let i=0;i
0 && nums[fast] * nums[getNext(fast)] > 0){ if(slow === fast){ if(slow === getNext(slow)) break; else return true; } slow = getNext(slow); fast = getNext(getNext(fast)); } let tmp = i; let val = nums[tmp]; while(val * nums[tmp] > 0){ let k = getNext(tmp); nums[tmp] = 0; tmp = k; } } return false;};

思路

首先需要解释一下题意,以示例1[2,-1,1,2,2]为例,最开始是索引0值为2,那么索引向前走2步到索引2值为1,继续向前走1步到达索引3值为2,再向前走2步循环索引回到0,所以这完成了一次循环,这里的起始点并不一定是索引0,起始点可以为任意索引位置,其次就是限制条件循环的长度必须大于1以及一个循环中的所有运动都必须沿着同一方向进行。

本题使用快慢指针来做,快指针每次走两步,慢指针每次走一步,如果能够达成循环那么快慢指针必定会相遇,当然在此处一步与两步指的是移动一个nums[i]的步长,不是移动index+1,首先定义一个n为数组长度以及getNext方法作为取得该点的下一步的索引值,之后遍历数组,根据定义,数组中不能存在0元素,所以以0为标记值进行剪枝,以慢指针指向i,快指针指向下一步的索引,while循环中第一个判断是保证慢指针与快指针指向的数组值符号相同,第二个判断是保证快指针指向的数组值与下一个快指针指向的数组值同号,保证一个循环中的所有运动都必须沿着同一方向进行,之后如果快慢指针相遇,则判断是否循环的长度为1,若循环的长度为1则不符合条件,便继续查找,否则就可以说明该数组中存在循环,之后便是slow指针走一步,fast指针走两部,最后需要剪枝,因为已经遍历过的元素不可能出现在循环当中,所以将以i为索引开始的每一步都置0,用以实现剪枝。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://leetcode-cn.com/problems/circular-array-loop

转载地址:http://apckz.baihongyu.com/

你可能感兴趣的文章
Mysql 整形列的字节与存储范围
查看>>
mysql 断电数据损坏,无法启动
查看>>
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询数据库所有表的字段信息
查看>>
【Java基础】什么是面向对象?
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>