LeetCode 697 数组的度
1.题目描述:
给定一个非空且只包含非负数的整数数组 nums,数组的度的定义是指数组里任一元素出现频数的最大值。
你的任务是在 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
2.题解:
求数组的度,本质还是求各个元素的出现次数,可以又哈希表来计数,哈希表中key时元素,value对应该元素出现的次数
**数组中的度:**数组中各元素出现次数的最大值。示例二中,数字2的度 最大为 3
**最短连续子数组:**拥有度为3 的 最大子数组长度为 6 = [2,2,3,1,4,2]
时间复杂度:O(N) ,对数组只遍历了一遍 ;
空间复杂度:O(N), 最坏情况下,最长数组长度跟nums 数组元素长度相等 。
c++:
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
unordered_map<int,int>cnt, minp, maxp ; //分别存储 各个元素的度,左、右边界
int d = 0 ;
for ( int i = 0; i < nums.size(); i++ ) {
int x = nums[i] ;
d = max(d, ++cnt[x]) ;
if (!minp.count(x)) minp[x] = i ; //初始化元素的左边界
maxp[x] = i ;
}
int res = INT_MAX ;
for (auto x : nums) {
if ( cnt[x] == d) { // 找到最大度对应的数字
res = min(res, maxp[x]-minp[x]+1 ) ;
}
}
return res ;
}
};
Golang
func findShortestSubArray(nums []int) int {
n := len(nums)
cnt := map[int]int{} //存每个数字对应的度
l := map[int]int{}//数字的左边界
r := map[int]int{}//数字的右边界
ans := 0 //记录数字的最大度
for i, v := range nums {
if _, ok := cnt[v]; !ok { // 若对应数的度,初始化数字左边界
l[v] = i
}
cnt[v]++
ans = max(ans, cnt[v])
r[v] = i
}
ans1 := n+1
for k, v := range cnt {
if v == ans {
ans1 = min(ans1, r[k] - l[k] + 1)
}
}
return ans1
}
func max (a, b int) int {
if a > b {
return a
}
return b
}
func min (a, b int) int {
if a < b {
return a
}
return b
}
原题:数组的度