链接
https://leetcode-cn.com/problems/degree-of-an-array/
耗时
解题:1 h 29 min
题解:13 min
题意
给定一个非空且只包含非负数的整数数组 nums,数组的度的定义是指数组里任一元素出现频数的最大值。
你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。
提示:
- nums.length 在1到 50,000 区间范围内。
- nums[i] 是一个在 0 到 49,999 范围内的整数。
思路
题意相当于是想找到频数最大的元素在数组中的首位元素的位置,长度就是首位元素位置的差。因为频数最大的元素可能不止一个,所以有题意是:返回数组中频数最大的元素中最小的长度。
定义一个结构体(包含元素的 值 和 位置),对这个结构体按元素值排序,元素值相同按位置排序。然后遍历排序后的结构体数组,相同的元素值都是挨着的,计数频率很方便,并且找到相同元素值得头尾,把他们对应的位置减一下就可以得到长度。
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
AC代码
class Solution {
public:
struct node {
int val;
int pos;
bool operator < (const node d) const {
return (val==d.val)?(pos<d.pos):(val<d.val);
}
};
int findShortestSubArray(vector<int>& nums) {
vector<node> valpos;
int n = nums.size();
for(int i = 0; i < n; ++i) {
valpos.push_back((node){nums[i], i});
}
sort(valpos.begin(), valpos.end());
int maxfreq = 0, minlen = 0;
int freq = 1, l = valpos[0].pos;
for(int i = 1; i <= n; ++i) {
if(i == n || valpos[i].val != valpos[i-1].val) {
if(freq > maxfreq) {
maxfreq = freq;
minlen = valpos[i-1].pos-l+1;
}
else if(freq == maxfreq) {
minlen = min(minlen, valpos[i-1].pos-l+1);
}
freq = 0;
if(i < n) l = valpos[i].pos;
}
freq++;
}
return minlen;
}
};