-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path457-CircularArrayLoop.go
More file actions
109 lines (97 loc) · 4.85 KB
/
457-CircularArrayLoop.go
File metadata and controls
109 lines (97 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main
// 457. Circular Array Loop
// You are playing a game involving a circular array of non-zero integers nums.
// Each nums[i] denotes the number of indices forward/backward you must move if you are located at index i:
// If nums[i] is positive, move nums[i] steps forward, and
// If nums[i] is negative, move nums[i] steps backward.
// Since the array is circular, you may assume that moving forward from the last element puts you on the first element,
// and moving backwards from the first element puts you on the last element.
// A cycle in the array consists of a sequence of indices seq of length k where:
// Following the movement rules above results in the repeating index sequence seq[0] -> seq[1] -> ... -> seq[k - 1] -> seq[0] -> ...
// Every nums[seq[j]] is either all positive or all negative.
// k > 1
// Return true if there is a cycle in nums, or false otherwise.
// Example 1:
// <img src="https://assets.leetcode.com/uploads/2022/09/01/img1.jpg" />
// Input: nums = [2,-1,1,2,2]
// Output: true
// Explanation: The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
// We can see the cycle 0 --> 2 --> 3 --> 0 --> ..., and all of its nodes are white (jumping in the same direction).
// Example 2:
// <img src="https://assets.leetcode.com/uploads/2022/09/01/img2.jpg" />
// Input: nums = [-1,-2,-3,-4,-5,6]
// Output: false
// Explanation: The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
// The only cycle is of size 1, so we return false.
// Example 3:
// <img src="https://assets.leetcode.com/uploads/2022/09/01/img3.jpg" />
// Input: nums = [1,-1,5,1,4]
// Output: true
// Explanation: The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
// We can see the cycle 0 --> 1 --> 0 --> ..., and while it is of size > 1, it has a node jumping forward and a node jumping backward, so it is not a cycle.
// We can see the cycle 3 --> 4 --> 3 --> ..., and all of its nodes are white (jumping in the same direction).
// Constraints:
// 1 <= nums.length <= 5000
// -1000 <= nums[i] <= 1000
// nums[i] != 0
// Follow up: Could you solve it in O(n) time complexity and O(1) extra space complexity?
import "fmt"
// 快慢指针
func circularArrayLoop(nums []int) bool {
if len(nums) == 0 {
return false
}
getNextIndex := func (nums []int, index int) int {
return ((nums[index]+index)%len(nums) + len(nums)) % len(nums)
}
for i := 0; i < len(nums); i++ {
if nums[i] == 0 {
continue
}
// slow/fast pointer
slow, fast, val := i, getNextIndex(nums, i), 0
for nums[fast]*nums[i] > 0 && nums[getNextIndex(nums, fast)]*nums[i] > 0 {
if slow == fast {
// check for loop with only one element
if slow == getNextIndex(nums, slow) {
break
}
return true
}
slow = getNextIndex(nums, slow)
fast = getNextIndex(nums, getNextIndex(nums, fast))
}
// loop not found, set all element along the way to 0
slow, val = i, nums[i]
for nums[slow]*val > 0 {
next := getNextIndex(nums, slow)
nums[slow] = 0
slow = next
}
}
return false
}
func main() {
// Example 1:
// <img src="https://assets.leetcode.com/uploads/2022/09/01/img1.jpg" />
// Input: nums = [2,-1,1,2,2]
// Output: true
// Explanation: The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
// We can see the cycle 0 --> 2 --> 3 --> 0 --> ..., and all of its nodes are white (jumping in the same direction).
fmt.Println(circularArrayLoop([]int{2,-1,1,2,2})) // true
// Example 2:
// <img src="https://assets.leetcode.com/uploads/2022/09/01/img2.jpg" />
// Input: nums = [-1,-2,-3,-4,-5,6]
// Output: false
// Explanation: The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
// The only cycle is of size 1, so we return false.
fmt.Println(circularArrayLoop([]int{-1,-2,-3,-4,-5,6})) // false
// Example 3:
// <img src="https://assets.leetcode.com/uploads/2022/09/01/img3.jpg" />
// Input: nums = [1,-1,5,1,4]
// Output: true
// Explanation: The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
// We can see the cycle 0 --> 1 --> 0 --> ..., and while it is of size > 1, it has a node jumping forward and a node jumping backward, so it is not a cycle.
// We can see the cycle 3 --> 4 --> 3 --> ..., and all of its nodes are white (jumping in the same direction).
fmt.Println(circularArrayLoop([]int{1,-1,5,1,4})) // true
}