问题:
degree:给定数组中重复最多元素的次数
求重复次数为degree的元素中,距离最短子数组的长度。
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
解法:
建立数据结构记录以下信息:
map:{ key: nums[i], value: { [0]:cout, [1]:start, [2]:end } }
cout:记录nums[i]出现的次数(degree)
start:nums[i]第一次出现的位置
end:nums[i]到目前位置,最后出现的位置
第一轮循环中,记录填充上述数据结构map,同时记录最大degree->maxcout
第二轮循环map,degree==maxcout的所有节点中,取res=end-start最短的。
tip:优化:
只循环一遍,把上述第二轮循环中,取res=end-start最短的取法也合并在第一轮。
if 当前节点的cout>maxcout
then
maxcout = 当前节点的cout
res = 当前节点的end-start
else if 当前节点的cout==maxcout
then
res = min(res, 当前节点的end-start)//取最小的距离
参考代码:
1 class Solution { 2 public: 3 int findShortestSubArray(vector<int>& nums) { 4 unordered_map<int, vector<int>> hash_num; 5 unordered_map<int, vector<int>>::iterator it; 6 //key:num[i], value:{cout,start,end} 7 int i; 8 int maxcout=0; 9 int res=INT_MAX; 10 for(i=0; i<nums.size(); i++){ 11 it = hash_num.find(nums[i]); 12 if(it!=hash_num.end()){//exist 13 it->second[0]++; 14 it->second[2]=i; 15 }else{//not exist 16 std::pair<int, vector<int>> tmpv = {nums[i], {1,i,i}}; 17 auto pr=hash_num.insert(tmpv); 18 it=pr.first; 19 } 20 if(maxcout<it->second[0]){ 21 res=it->second[2]-it->second[1]+1; 22 maxcout=it->second[0]; 23 }else if(maxcout==it->second[0]){ 24 res=min(res, it->second[2]-it->second[1]+1); 25 } 26 } 27 /*for(it=hash_num.begin(); it!=hash_num.end(); it++){ 28 if(it->second[0]==maxcout){ 29 res=min(res, it->second[2]-it->second[1]+1); 30 } 31 }*/ 32 return res; 33 } 34 };