原题地址(简单)
方法1—哈希表
思路
感觉这题其实可以来个中等难度的。。。
思路就是找出数组的度,然后找出出现次数等于度的那些数,然后再找出这些数的始末位置,看看哪个长度最小,就酱……
代码
开始只想到了用unordered_map存储数和其出现次数,代码写的较为麻烦些。
class Solution {public:int findShortestSubArray(vector<int>& nums) {unordered_map<int, int> um;for(auto num : nums) um[num]++;vector<int> v;int n = nums.size(), ans = n, freq = 0;for(auto it = um.begin(); it!= um.end(); it++) { // 找出度if(it->second > freq) freq = it->second;}for(auto it = um.begin(); it!= um.end(); it++) { //找出出现次数为度的那些数if(it->second == freq) v.push_back(it->first);}for(int i=0; i<v.size(); i++) { // 寻找这些数的始末位置int l = 0, r = n - 1;while(l < n) {if(nums[l] != v[i])l++;else break;}while(r >= 0) {if(nums[r] != v[i])r--;else break;}ans = min(ans, r - l + 1);}return ans;}};
后来看了题解,发现如果用unordered_map同时存储数的出现次数以及始末位置,会更快.
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
unordered_map<int, vector<int>> um;
int n = nums.size(), ans = n, freq = 0;
for(int i = 0; i < n; i++) {
if(um.count(nums[i])) {
um[nums[i]][0]++;
um[nums[i]][2] = i;
}
else {
um[nums[i]] = {1, i, i};
}
}
for(auto it = um.begin(); it!= um.end(); it++) {
if(it->second[0] > freq) {
freq = it->second[0];
ans = it->second[2] - it->second[1] + 1;
}
else if(it->second[0] == freq)
ans = min(ans, it->second[2] - it->second[1] + 1);
}
return ans;
}
};
时空复杂度
均为O(N)
