[Swift]LeetCode697. 数组的度 | Degree of an Array

Given a non-empty array of non-negative integers nums, the degreeof this array is defined as the maximum frequency of any one of its elements.

Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums.

Example 1:

Input: [1, 2, 2, 3, 1]
Output: 2
Explanation: 
The input array has a degree of 2 because both elements 1 and 2 appear twice.
Of the subarrays that have the same degree:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
The shortest length is 2. So return 2. 

Example 2:

Input: [1,2,2,3,1,4,2]
Output: 6 

Note:

  • nums.length will be between 1 and 50,000.
  • nums[i] will be an integer between 0 and 49,999.

给定一个非空且只包含非负数的整数数组 nums, 数组的度的定义是指数组里任一元素出现频数的最大值。

你的任务是找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。

示例 1:

输入: [1, 2, 2, 3, 1]
输出: 2
解释: 
输入数组的度是2,因为元素1和2的出现频数最大,均为2.
连续子数组里面拥有相同度的有如下所示:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
最短连续子数组[2, 2]的长度为2,所以返回2.

示例 2:

输入: [1,2,2,3,1,4,2]
输出: 6

注意:

  • nums.length 在1到50,000区间范围内。
  • nums[i] 是一个在0到49,999范围内的整数。

Runtime: 220 ms
Memory Usage: 20.5 MB
 1 class Solution {
 2     func findShortestSubArray(_ nums: [Int]) -> Int {
 3         guard nums.count > 1 else {
 4             return nums.count
 5         }
 6         var dic: [Int:Int] = [:]
 7         for i in 0..<nums.count {
 8             let num: Int = nums[i]
 9             if dic.keys.contains(num) {
10                 dic[num] = dic[num]! + 1
11             } else {
12                 dic[num] = 1
13             }
14         }
15         var max = 0//出现最大次数
16         var maxNums: [Int] = []//出现最大次数元素数组
17         for j in dic.keys {
18             let v = dic[j]!
19             if v > max {
20                 maxNums.removeAll()
21                 maxNums.append(j)
22                 max = v
23             } else if v == max {
24                 maxNums.append(j)
25             }
26         }
27         if max < 2 {
28             return 1
29         }
30         var minChildArrayCount = nums.count//最短连续子数组长度
31         for a in maxNums {
32             var start: Int = 0,end: Int = nums.count-1//开始位置,结束位置
33             for s in nums {
34                 if s != a {
35                     start += 1
36                 } else {
37                     break
38                 }
39             }
40             for e in nums.reversed() {
41                 if e != a {
42                     end -= 1
43                 } else {
44                     break
45                 }
46             }
47             minChildArrayCount = min(minChildArrayCount, end-start+1)
48         }
49         return minChildArrayCount
50     }
51 }

228ms

 1 class Solution {
 2     func findShortestSubArray(_ nums: [Int]) -> Int {        
 3         var starts = [Int: Int]()
 4         var ends = [Int: Int]()
 5         var counts = [Int: Int]()
 6         var maxCount = Int.min
 7         
 8         for i in 0..<nums.count {            
 9             let num = nums[i]
10             if starts[num] == nil {
11                 starts[num] = i
12             }
13             ends[num] = i
14             counts[num] = ( counts[num] ?? 0 ) + 1            
15             maxCount = max(counts[num]!, maxCount)
16         }        
17 
18         var result = Int.max
19         for key in counts.keys {            
20             if counts[key]! < maxCount {
21                 continue
22             }
23             
24             result = min(ends[key]! - starts[key]! + 1, result)
25         }        
26 
27         return result
28     }
29 }

240ms

 1 class Solution {
 2     func findShortestSubArray(_ nums: [Int]) -> Int {
 3         var dict = [Int: [Int]]()
 4         var frequency = Dictionary( nums.map{ ($0, 1) }, uniquingKeysWith: +)
 5         var degree = 0
 6         for (key, value) in frequency {
 7             degree = max(value, degree)
 8         }
 9         var degreeItemArray = Set<Int>()
10         for (key, value) in frequency {
11             if value == degree {
12                 degreeItemArray.insert(key)
13             }
14         }
15         for i in 0..<nums.count {
16             guard degreeItemArray.contains(nums[i]) else {
17                 continue
18             }
19             dict[nums[i]] = dict[nums[i]] ?? [i, i]
20             var items = dict[nums[i]]!
21             if i > items[1] {
22                 items[1] = i
23             }
24             dict[nums[i]] = items
25         }
26         var result = Int.max
27         for (key, value) in dict {
28             result = min(result, value[1] - value[0] + 1)
29         }
30         return result
31     }
32 }

264ms

 1 class ItemInfo {
 2     let value: Int
 3     var count: Int
 4     var startIndex: Int
 5     var endIndex: Int
 6     
 7     var length: Int {
 8         return self.endIndex - self.startIndex + 1
 9     }
10     
11     init(value: Int, at index: Int) {
12         self.value = value
13         self.count = 1
14         self.startIndex = index
15         self.endIndex = index
16     }
17     
18     func addItem(at index: Int) -> Self {
19         self.count += 1
20         self.startIndex = min(startIndex, index)
21         self.endIndex = max(endIndex, index)
22         
23         return self
24     }
25 }
26 
27 class Solution {
28     func findShortestSubArray(_ nums: [Int]) -> Int {
29         guard nums.count > 1 else {
30             return nums.count
31         }
32         
33         var info: [Int: ItemInfo] = [:]
34         
35         for (index, num) in nums.enumerated() {
36             if let currentInfo = info[num] {
37                 info[num] = currentInfo.addItem(at: index)
38             } else {
39                 info[num] = ItemInfo(value: num, at: index)
40             }
41         }
42         
43         if let max = info.max(by: { (arg1, arg2) -> Bool in
44             return arg1.value.count < arg2.value.count || (arg1.value.count == arg2.value.count && arg1.value.length > arg2.value.length)
45         }) {
46             return max.value.length
47         } else {
48             return -1
49         }
50     }
51 }

284ms

 1 class Solution {
 2     func findShortestSubArray(_ nums: [Int]) -> Int {
 3         var firstIndexMap = [Int: Int]()
 4         var lastIndexMap = [Int: Int]()
 5         var countMap = [Int: Int]()
 6 
 7         // Find the "degree" (most frequent element count)
 8         var maxCount = 0
 9         for (i, num) in nums.enumerated() {
10             if let count = countMap[num] {
11                 maxCount = max(maxCount, count + 1)
12                 countMap[num] = count + 1
13                 lastIndexMap[num] = i
14             } else {
15                 countMap[num] = 1
16                 firstIndexMap[num] = i
17             }
18             
19             maxCount = max(maxCount, countMap[num]!)
20         }
21         
22         guard maxCount > 1 else { return maxCount }
23 
24         let maxDict = countMap.filter { k, v in v == maxCount }
25 
26         var lengthsDict = [Int: Int]()
27         for (key, _) in maxDict {
28             lengthsDict[key] = lastIndexMap[key]! - firstIndexMap[key]! + 1
29         }
30 
31         let minValue = [Int](lengthsDict.values).min() ?? 0
32 
33         return minValue
34     }
35 }

440ms

 1 class Solution {
 2     func findShortestSubArray(_ nums: [Int]) -> Int {
 3         
 4         if nums.count <= 1 {
 5             return nums.count
 6         }
 7         
 8         var dict = [Int: [String: Int]]()
 9         
10         for i in 0..<nums.count {
11             
12             let value = nums[i]
13             
14             if dict[value] == nil {
15                 dict[value] = [
16                     "start": i,
17                     "end": i,
18                     "count": 1
19                 ]
20             } else {
21                 dict[value]!["end"] = i
22                 dict[value]!["count"] = dict[value]!["count"]! + 1
23             }
24         }
25         
26         var count = Int.min
27         var degree = Int.max
28         
29         for key in dict.keys {
30             
31             let d = dict[key]
32             
33             guard let c = d!["count"] else {
34                 continue
35             }
36             
37             if c < count {
38                 continue
39             }
40             
41             guard let s = d!["start"] else {
42                 continue
43             }
44             
45             guard let e = d!["end"] else {
46                 continue
47             }
48             
49             if c > count {
50                 degree = e - s + 1
51             } else {
52                 degree = min(degree, e - s + 1)
53             }
54             
55             count = max(count, c)
56         }
57         
58         return degree == Int.max ? 1 : degree
59     }
60 }

猜你喜欢

转载自www.cnblogs.com/strengthen/p/10502691.html
今日推荐