LeetCode 题解工作台

环形数组是否存在循环

存在一个不含 0 的 环形 数组 nums ,每个 nums[i] 都表示位于下标 i 的角色应该向前或向后移动的下标个数: 如果 nums[i] 是正数, 向前 (下标递增方向)移动 nums[i] 步 如果 nums[i] 是负数, 向后 (下标递减方向)移动 abs(nums[i]) 步 因为…

category

3

题型

code_blocks

4

代码语言

hub

3

相关题

当前训练重点

中等 · 数组·哈希·扫描

bolt

答案摘要

class Solution: def circularArrayLoop(self, nums: List[int]) -> bool:

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 数组·哈希·扫描 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

存在一个不含 0 环形 数组 nums ,每个 nums[i] 都表示位于下标 i 的角色应该向前或向后移动的下标个数:

  • 如果 nums[i] 是正数,向前(下标递增方向)移动 nums[i] 步
  • 如果 nums[i] 是负数,向后(下标递减方向)移动 abs(nums[i]) 步

因为数组是 环形 的,所以可以假设从最后一个元素向前移动一步会到达第一个元素,而第一个元素向后移动一步会到达最后一个元素。

数组中的 循环 由长度为 k 的下标序列 seq 标识:

  • 遵循上述移动规则将导致一组重复下标序列 seq[0] -> seq[1] -> ... -> seq[k - 1] -> seq[0] -> ...
  • 所有 nums[seq[j]] 应当不是 全正 就是 全负
  • k > 1

如果 nums 中存在循环,返回 true ;否则,返回 false

 

示例 1:

输入:nums = [2,-1,1,2,2]
输出:true
解释:图片展示了节点间如何连接。白色节点向前跳跃,而红色节点向后跳跃。
我们可以看到存在循环,按下标 0 -> 2 -> 3 -> 0 --> ...,并且其中的所有节点都是白色(以相同方向跳跃)。

示例 2:

输入:nums = [-1,-2,-3,-4,-5,6]
输出:false
解释:图片展示了节点间如何连接。白色节点向前跳跃,而红色节点向后跳跃。
唯一的循环长度为 1,所以返回 false。

示例 3:

输入:nums = [1,-1,5,1,4]
输出:true
解释:图片展示了节点间如何连接。白色节点向前跳跃,而红色节点向后跳跃。
我们可以看到存在循环,按下标 0 --> 1 --> 0 --> ...,当它的大小大于 1 时,它有一个向前跳的节点和一个向后跳的节点,所以 它不是一个循环。
我们可以看到存在循环,按下标 3 --> 4 --> 3 --> ...,并且其中的所有节点都是白色(以相同方向跳跃)。

 

提示:

  • 1 <= nums.length <= 5000
  • -1000 <= nums[i] <= 1000
  • nums[i] != 0

 

进阶:你能设计一个时间复杂度为 O(n) 且额外空间复杂度为 O(1) 的算法吗?

lightbulb

解题思路

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution:
    def circularArrayLoop(self, nums: List[int]) -> bool:
        n = len(nums)

        def next(i):
            return (i + nums[i] % n + n) % n

        for i in range(n):
            if nums[i] == 0:
                continue
            slow, fast = i, next(i)
            while nums[slow] * nums[fast] > 0 and nums[slow] * nums[next(fast)] > 0:
                if slow == fast:
                    if slow != next(slow):
                        return True
                    break
                slow, fast = next(slow), next(next(fast))
            j = i
            while nums[j] * nums[next(j)] > 0:
                nums[j] = 0
                j = next(j)
        return False
speed

复杂度分析

指标
时间complexity is O(n) because each index is visited at most twice by slow and fast pointers or hash markers. Space complexity is O(n) for the hash/visited array, though it can be reduced to O(1) using in-place marking strategies without altering the array.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Asks about cycle detection with consistent direction in circular arrays

  • question_mark

    Questions about using fast/slow pointers versus hash arrays

  • question_mark

    Tests edge cases like single-length loops and direction changes

warning

常见陷阱

外企场景
  • error

    Failing to handle single-element loops, which are invalid

  • error

    Mixing forward and backward steps in the same cycle

  • error

    Not accounting for array wrap-around properly when calculating next index

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Allowing zero elements as valid steps, changing cycle conditions

  • arrow_right_alt

    Finding the longest valid loop instead of any loop

  • arrow_right_alt

    Detecting multiple non-overlapping cycles in the same array

help

常见问题

外企场景

环形数组是否存在循环题解:数组·哈希·扫描 | LeetCode #457 中等