[Swift]LeetCode457. 环形数组循环 | Circular Array Loop
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10343272.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
You are given an array of positive and negative integers. If a number n at an index is positive, then move forward n steps. Conversely, if it's negative (-n), move backward n steps. Assume the first element of the array is forward next to the last element, and the last element is backward next to the first element. Determine if there is a loop in this array. A loop starts and ends at a particular index with more than 1 element along the loop. The loop must be "forward" or "backward'.
Example 1: Given the array [2, -1, 1, 2, 2], there is a loop, from index 0 -> 2 -> 3 -> 0.
Example 2: Given the array [-1, 2], there is no loop.
Note: The given array is guaranteed to contain no element "0".
Can you do it in O(n) time complexity and O(1) space complexity?
给定一组含有正整数和负整数的数组。如果某个索引中的 n 是正数的,则向前移动 n 个索引。相反,如果是负数(-n),则向后移动 n 个索引。
假设数组首尾相接。判断数组中是否有环。环中至少包含 2 个元素。环中的元素一律“向前”或者一律“向后”。
示例 1:给定数组 [2, -1, 1, 2, 2], 有一个循环,从索引 0 -> 2 -> 3 -> 0。
示例 2:给定数组[-1, 2], 没有循环。
注意:给定数组保证不包含元素"0"。
你能写出时间复杂度为 O(n) 且空间复杂度为 O(1) 的算法吗?
8ms
1 class Solution { 2 func circularArrayLoop(_ nums: [Int]) -> Bool { 3 var m:[Int:Int] = [Int:Int]() 4 var n:Int = nums.count 5 var visited:[Bool] = [Bool](repeating:false,count:n) 6 for i in 0..<n 7 { 8 if visited[i] {continue} 9 var cur:Int = i 10 while(true) 11 { 12 visited[cur] = true 13 var next:Int = (cur + nums[cur]) % n 14 if next < 0 {next += n} 15 if next == cur || nums[next] * nums[cur] < 0 16 { 17 break 18 } 19 if m[next] != nil {return true} 20 m[cur] = next 21 cur = next 22 } 23 } 24 return false 25 } 26 }
8ms
1 class Solution { 2 func circularArrayLoop(_ nums: [Int]) -> Bool { 3 4 var visitedIndexes: Set<Int> = [] 5 6 for i in 0..<nums.count { 7 if visitedIndexes.contains(i) { 8 continue 9 } 10 11 var currentIndex = i 12 var isForwardLoop = nums[currentIndex] > 0 13 var lastIndex = -1 14 var currentIndexes: Set<Int> = [] 15 16 while visitedIndexes.count < nums.count { 17 visitedIndexes.insert(currentIndex) 18 currentIndexes.insert(currentIndex) 19 20 let nextIndex = findNextIndex(nums: nums, index: currentIndex) 21 22 if isForwardLoop && nums[nextIndex] < 0 { 23 break // we are doing foward loop, and this is backward 24 } else if !isForwardLoop && nums[nextIndex] > 0 { 25 break // we are doing backward loop, and this is forward 26 } else if nextIndex == lastIndex { 27 // we are looping without 1 number in-between which is fine 28 break 29 } else if currentIndexes.contains(nextIndex) { 30 return true // there is a loop 31 } else { 32 lastIndex = currentIndex 33 currentIndex = nextIndex 34 } 35 } 36 } 37 38 return false 39 } 40 41 func findNextIndex(nums: [Int], index: Int) -> Int { 42 var number = nums[index] % nums.count 43 44 var nextIndex = number 45 46 if number > 0 { 47 nextIndex = (index + number) % nums.count 48 } else if number < 0 { 49 nextIndex = (index + number) 50 if nextIndex < 0 { 51 nextIndex += nums.count // wrap it around 52 } 53 } 54 55 return nextIndex 56 } 57 }