【LeetCode】457. Circular Array Loop 环形数组是否存在循环 解题报告(Python)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/circular-array-loop/
题目描述
You are given a circular array nums of positive and negative integers. If a number k at an index is positive, then move forward k steps. Conversely, if it’s negative (-k), move backward k steps. Since the array is circular, you may assume that the last element’s next element is the first element, and the first element’s previous element is the last element.
Determine if there is a loop (or a cycle) in nums. A cycle must start and end at the same index and the cycle’s length > 1. Furthermore, movements in a cycle must all follow a single direction. In other words, a cycle must not consist of both forward and backward movements.
Example 1:
Input: [2,-1,1,2,2]
Output: true
Explanation: There is a cycle, from index 0 -> 2 -> 3 -> 0. The cycle's length is 3.
Example 2:
Input: [-1,2]
Output: false
Explanation: The movement from index 1 -> 1 -> 1 ... is not a cycle, because the cycle's length is 1. By definition the cycle's length must be greater than 1.
Example 3:
Input: [-2,1,-1,-2,-2]
Output: false
Explanation: The movement from index 1 -> 2 -> 1 -> ... is not a cycle, because movement from index 1 -> 2 is a forward movement, but movement from index 2 -> 1 is a backward movement. All movements in a cycle must follow a single direction.
Note:
- -1000 ≤ nums[i] ≤ 1000
- nums[i] ≠ 0
- 1 ≤ nums.length ≤ 5000
Follow up:
Could you solve it in O(n) time complexity and O(1) extra space complexity?
题目大意
首先,要理解题目中的「环形数组」是什么。「环形数组」就是在逻辑上首尾相接的数组,即最后一个元素和第一个元素在逻辑上是相邻的(在物理存储上仍然是个普通的数组)。
那么环形数组中存在循环是什么意思呢?这就是说,在环形数组中,每个位置存储的元素表示当前位置应该向前/向后移动的步数。如果在环形数组中绕了一圈又回到了原地,那么说明数组中存在循环。
举个例子,在环形数组 [2, -1, 1, 2, 2] 中,存在循环:

同时,题目约定了循环的条件:
- 所有
nums[seq[j]]应当不是 全正 就是 全负,即只能沿着一个方向走。 k > 1,即要求环的大小 > 1。
题目的示例 2 和 3 说明了上述循环的条件。
示例 2 ,nums = [-1,2],不算循环的原因是,循环中只有一个元素:

示例 3,nums = [-2,1,-1,-2,-2],不算循环的原因是,循环中同时存在正、负数。

另外,需要提醒大家的是:循环的起点并不一定是位置 0.
解题思路
快慢指针
相信大家都做过「判断链表中是否有环」的题目,这两题的思路是一致的,常见的思路就是快慢指针,在链表问题中,快指针每次走 2 步,慢指针每次走 1 步。当快慢指针相遇的时候,说明存在环。
在本题中,题目规定了数组中每个位置存储的元素就是每次需要移动的步数。所以快指针、慢指针每次走的步数等于 nums[fast]、nums[slow];在每一次的移动中,快指针需要走 2 次,而慢指针需要走 1 次。当快慢指针相遇的时候,说明有环。
起始时,让快指针先比慢指针多走一步,当两者在满足题目的两个限制条件的情况下,快满指针能够相遇,则说明有环。
这个题难点在于题目的两个限制条件:
- 在每次循环的过程中,必须保证所经历过的所有数字都是同号的。
- 那么,在快指针经历过的每个位置都要判断一下和出发点的数字是不是相同的符号。
- 当快慢指针相遇的时候,还要判断环的大小不是 1。
- 所以,找到相遇点的位置后,如果再走 1 步,判断是不是自己。
下面的动图展示了在环形数组 [2, -1, 1, 2, 2] 中,如何利用快慢指针寻找判断环形数组中是否存在环。

代码
在下面的代码中,我定义了一个 nextpos(index)的函数,用于判断每次移动后应该走到哪个位置。
Python代码如下:
class Solution(object):
def circularArrayLoop(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
N, self.nums = len(nums), nums
for i in range(N):
slow = i
fast = self.nextpos(slow)
while nums[fast] * nums[i] > 0 and nums[self.nextpos(fast)] * nums[i] > 0:
if fast == slow:
if slow == self.nextpos(slow):
break
return True
slow = self.nextpos(slow)
fast = self.nextpos(self.nextpos(fast))
return False
def nextpos(self, index):
N = len(self.nums)
return (index + self.nums[index] + N) % N
日期
2019 年 2 月 27 日 —— 二月就要完了
2021 年 8 月 7 日 —— 开始更新算法每日一题
【LeetCode】457. Circular Array Loop 环形数组是否存在循环 解题报告(Python)的更多相关文章
- [LeetCode] 457. Circular Array Loop 环形数组循环
You are given a circular array nums of positive and negative integers. If a number k at an index is ...
- [LeetCode] Circular Array Loop 环形数组循环
You are given an array of positive and negative integers. If a number n at an index is positive, the ...
- LeetCode 457. Circular Array Loop
原题链接在这里:https://leetcode.com/problems/circular-array-loop/ 题目: You are given a circular array nums o ...
- LeetCode 1013 Partition Array Into Three Parts With Equal Sum 解题报告
题目要求 Given an array A of integers, return true if and only if we can partition the array into three ...
- 【LeetCode】109. Convert Sorted List to Binary Search Tree 解题报告(Python)
[LeetCode]109. Convert Sorted List to Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...
- 【LeetCode】378. Kth Smallest Element in a Sorted Matrix 解题报告(Python)
[LeetCode]378. Kth Smallest Element in a Sorted Matrix 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...
- 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)
[LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...
- 【LeetCode】331. Verify Preorder Serialization of a Binary Tree 解题报告(Python)
[LeetCode]331. Verify Preorder Serialization of a Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https:/ ...
- 【LeetCode】452. Minimum Number of Arrows to Burst Balloons 解题报告(Python)
[LeetCode]452. Minimum Number of Arrows to Burst Balloons 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https ...
随机推荐
- C语言 fastq文件转换为fasta文件
目前只能处理短序列,若要处理长序列,可按照https://www.cnblogs.com/mmtinfo/p/13036039.html的读取方法. 1 #include <stdio.h> ...
- Telink BLE MESH PWM波的小结
本本针对Telink BLE MESH SDK 灯控的使用进行说明. 1.调整灯光的频率 默认情况下 SDK PWM波的频率是 600HZ的,有时我们需要将它调整频率,例如调整为4K,只需要更改参数 ...
- adblock plus-看下图你就懂
- mysql 实现某年单季度内的品牌TOPn销量在此年此单季度内销量占比
数据表: 结果表: mysql语句:
- Go语言核心36讲(Go语言实战与应用二十一)--学习笔记
43 | bufio包中的数据类型(下) 在上一篇文章中,我提到了bufio包中的数据类型主要有Reader.Scanner.Writer和ReadWriter.并着重讲到了bufio.Reader类 ...
- 【.Net】使用委托实现被引用的项目向上级项目的消息传递事件
前言:在实际项目过程中,经常可能遇到被引用的项目要向上传递消息,但是又不能通过方法进行返回等操作,这个时候委托就派上用场了.以下使用委托,来实现被引用的项目向上传递消息的小教程,欢迎各位大佬提供建议. ...
- 【Python机器学习实战】聚类算法(1)——K-Means聚类
实战部分主要针对某一具体算法对其原理进行较为详细的介绍,然后进行简单地实现(可能对算法性能考虑欠缺),这一部分主要介绍一些常见的一些聚类算法. K-means聚类算法 0.聚类算法算法简介 聚类算法算 ...
- 【Reverse】DLL注入
DLL注入就是将dll粘贴到指定的进程空间中,通过dll状态触发目标事件 DLL注入的大概流程 https://uploader.shimo.im/f/CXFwwkEH6FPM0rtT.png!thu ...
- HttpClient连接池设置引发的一次雪崩
事件背景 我在凤巢团队独立搭建和运维的一个高流量的推广实况系统,是通过HttpClient 调用大搜的实况服务.最近经常出现Address already in use (Bind failed)的问 ...
- 格式化代码(Eclipse 格式化代码块快捷键:Ctrl+Shift+F)
1.格式化java代码 : ①Ctrl+Shift+F 但是我们会遇到按 Ctrl+Shift+F不起作用的时候? Ctrl+Shift+F 在搜狗拼音里是简繁替换.一旦安装搜狗拼音这个快 ...