为有牺牲多壮志,敢教日月换新天。

[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 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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 }

 

posted @ 2019-01-31 19:02  为敢技术  阅读(352)  评论(0编辑  收藏  举报