作者: 负雪明烛
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:

  1. -1000 ≤ nums[i] ≤ 1000
  2. nums[i] ≠ 0
  3. 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. 所以,找到相遇点的位置后,如果再走 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)的更多相关文章

  1. [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 ...

  2. [LeetCode] Circular Array Loop 环形数组循环

    You are given an array of positive and negative integers. If a number n at an index is positive, the ...

  3. LeetCode 457. Circular Array Loop

    原题链接在这里:https://leetcode.com/problems/circular-array-loop/ 题目: You are given a circular array nums o ...

  4. 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  ...

  5. 【LeetCode】109. Convert Sorted List to Binary Search Tree 解题报告(Python)

    [LeetCode]109. Convert Sorted List to Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...

  6. 【LeetCode】378. Kth Smallest Element in a Sorted Matrix 解题报告(Python)

    [LeetCode]378. Kth Smallest Element in a Sorted Matrix 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...

  7. 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)

    [LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...

  8. 【LeetCode】331. Verify Preorder Serialization of a Binary Tree 解题报告(Python)

    [LeetCode]331. Verify Preorder Serialization of a Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https:/ ...

  9. 【LeetCode】452. Minimum Number of Arrows to Burst Balloons 解题报告(Python)

    [LeetCode]452. Minimum Number of Arrows to Burst Balloons 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https ...

随机推荐

  1. 【GS文献】测序时代植物复杂性状育种之基因组选择

    综述:Genomic Selection in the Era of Next Generation Sequencing for Complex Traits in Plant Breeding 要 ...

  2. nginx负均

    Nginx负载均衡详解 上一篇中我说啦nginx有哪些中负载均衡算法.这一结我就给如果操作配置的给大家做详细说明下. 首先给大家说下upstream这个配置的,这个配置是写一组被代理的服务器地址,然后 ...

  3. 简单的Mybatis程序

    1.新建一个普通Maven项目,导入 mybatis.mysql.junit(用于测试)3个依赖 Mybatis <dependency> <groupId>org.mybat ...

  4. 学习java的第九天

    一.今日收获 1.java完全学习手册第二章程序流程控制中的顺序结构与选择结构 2.学习了java中选择的一些语句和关键词 二.今日问题 1.例题验证有错的情况 2.哔哩哔哩教学视频的一些术语不太理解 ...

  5. day08 文件属性

    day08 系统目录 今日内容 一.重要目录 1./usr 2./var 3./proc 二.文件的属性 1.文件属性的介绍 2.文件属性的详述 3.企业案例 /usr 安装第三方软件的目录: 1./ ...

  6. c学习 - 第七章:数组

    7.3.6 字符串处理函数 (1).puts(字符数组) 字符串输出到终端 (2).gets(字符数组) 从标准输入获取字符串(包括空格) (3).strcat(字符数组1,字符数组2) 连接两个字符 ...

  7. Linux基础命令---enable开启shell命令

    enable enable指令用来关闭或者激活shell内部命令.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora. 1.语法       enable [-a]   ...

  8. android 调用相机拍照及相册

    调用系统相机拍照: private Button btnDyxj; private ImageView img1; private File tempFile; btnDyxj = (Button) ...

  9. 【Java基础】Java反射——Private Fields and Methods

    Despite the common belief it is actually possible to access private fields and methods of other clas ...

  10. 莫烦python教程学习笔记——使用波士顿数据集、生成用于回归的数据集

    # View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...