File tree 2 files changed +112
-0
lines changed
solution/0457.Circular Array Loop
2 files changed +112
-0
lines changed Original file line number Diff line number Diff line change
1
+ # 环形数组循环
2
+
3
+ ### 题目描述
4
+
5
+ 给定一个含有正整数和负整数的** 环** 形数组 ` nums ` 。 如果某个索引中的数 k 为正数,则向前移动 k 个索引。相反,如果是负数 (-k),则向后移动 k 个索引。因为数组是环形的,所以可以假设最后一个元素的下一个元素是第一个元素,而第一个元素的前一个元素是最后一个元素。
6
+
7
+ 确定 nums 中是否存在循环(或周期)。循环必须在相同的索引处开始和结束并且循环长度 > 1。此外,一个循环中的所有运动都必须沿着同一方向进行。换句话说,一个循环中不能同时包括向前的运动和向后的运动。
8
+
9
+
10
+ ** 示例 1**
11
+
12
+ ```
13
+ 输入:[2,-1,1,2,2]
14
+ 输出:true
15
+ 解释:存在循环,按索引 0 -> 2 -> 3 -> 0 。循环长度为 3 。
16
+ ```
17
+
18
+ ** 示例 2**
19
+
20
+ ```
21
+ 输入:[-1,2]
22
+ 输出:false
23
+ 解释:按索引 1 -> 1 -> 1 ... 的运动无法构成循环,因为循环的长度为 1 。根据定义,循环的长度必须大于 1 。
24
+ ```
25
+
26
+ ** 示例 3**
27
+
28
+ ```
29
+ 输入:[-2,1,-1,-2,-2]
30
+ 输出:false
31
+ 解释:按索引 1 -> 2 -> 1 -> ... 的运动无法构成循环,因为按索引 1 -> 2 的运动是向前的运动,而按索引 2 -> 1 的运动是向后的运动。一个循环中的所有运动都必须沿着同一方向进行。
32
+ ```
33
+
34
+ ** 提示**
35
+
36
+ 1 . -1000 ≤ nums[ i] ≤ 1000
37
+ 2 . nums[ i] ≠ 0
38
+ 3 . 1 ≤ nums.length ≤ 5000
39
+
40
+ ** 进阶**
41
+
42
+ 你能写出时间时间复杂度为 ** O(n)** 和额外空间复杂度为 ** O(1)** 的算法吗?
43
+
44
+
45
+ ### 解题思路
46
+
47
+ ** 思路**
48
+
49
+ 若时间复杂度为 ** O(n^2)** 则不用记录,双重遍历就完事了。降低时间复杂度为 ** O(n)** 首先想到设置一个` visit ` 数组来记录是否被访问。若要空间复杂度为 ** O(1)** ,考虑` -1000 ≤ nums[i] ≤ 1000 ` ,可以用大于1000或小于-1000来记录是否被访问。需要注意的是循环长度要大于` 1 ` ,在一条链路中可能会出现` 0 -> 2 -> 3 -> 3 ` 这种在尾部存在的自循环。
50
+
51
+ ** 算法**
52
+
53
+ ** python**
54
+
55
+ ``` python
56
+ class Solution :
57
+ def circularArrayLoop (self , nums : ' List[int]' ) -> ' bool' :
58
+ flag = 1000
59
+ lent = len (nums)
60
+ drt = 1 # -1->left 1->right
61
+ for loc in range (lent):
62
+ if nums[loc] > 1000 :
63
+ continue
64
+ if nums[loc] < 0 :
65
+ drt = - 1
66
+ else :
67
+ drt = 1
68
+ ct = (loc + nums[loc]) % lent
69
+ flag += 1
70
+ nums[loc] = flag
71
+ start = flag
72
+ tmp = ct
73
+ while - 1000 <= nums[ct] <= 1000 :
74
+ if nums[ct] * drt < 0 :
75
+ break
76
+ tmp = ct
77
+ ct = (ct + nums[ct]) % lent
78
+ flag += 1
79
+ nums[tmp] = flag
80
+ else :
81
+ if nums[ct] != nums[tmp] and nums[ct] >= start:
82
+ return True
83
+ return False
84
+ ```
Original file line number Diff line number Diff line change
1
+ class Solution :
2
+ def circularArrayLoop (self , nums : 'List[int]' ) -> 'bool' :
3
+ flag = 1000
4
+ lent = len (nums )
5
+ drt = 1 # -1->left 1->right
6
+ for loc in range (lent ):
7
+ if nums [loc ] > 1000 :
8
+ continue
9
+ if nums [loc ] < 0 :
10
+ drt = - 1
11
+ else :
12
+ drt = 1
13
+ ct = (loc + nums [loc ]) % lent
14
+ flag += 1
15
+ nums [loc ] = flag
16
+ start = flag
17
+ tmp = ct
18
+ while - 1000 <= nums [ct ] <= 1000 :
19
+ if nums [ct ] * drt < 0 :
20
+ break
21
+ tmp = ct
22
+ ct = (ct + nums [ct ]) % lent
23
+ flag += 1
24
+ nums [tmp ] = flag
25
+ else :
26
+ if nums [ct ] != nums [tmp ] and nums [ct ] >= start :
27
+ return True
28
+ return False
You can’t perform that action at this time.
0 commit comments