1、比较笨的方式是先用vector给每一个元素计数(注意这个vector的长度,原数组可能有负数),然后找到degree并记录哪些元素是候选项;再针对每一个候选项遍历原数组。
很笨的方法但很有效;
if(nums.size() == 1)
return 1;
vector<int>::iterator iter = max_element(nums.begin(), nums.end());
vector<int> flag(*iter+1, 0);
vector<int> possibleEleNum;
for(int i = 0; i < nums.size(); i++){
flag[nums[i]]++;
}
auto maxDegree = max_element(flag.begin(), flag.end());
if(*maxDegree == 1)
return 1;
for(int i = 0; i < *iter+1; i++){
if(flag[i] == *maxDegree)
possibleEleNum.push_back(i);
}
int minLength = 50000;
for(int j = 0; j < possibleEleNum.size(); j++){
int count = 0;
int length = 0;
for(int i = 0; i < nums.size(); i++){
if(nums[i] == possibleEleNum[j])
count++;
if(count)
length++;
if(count == *maxDegree)
break;
}
if(length < minLength)
minLength = length;
}
return minLength;
2、更进一步的方式是用map对每一个元素构建一个起始位置对(或出现位置的序列)。在构建键值的同时比较长度与出现次数,以降低复杂度。
当构建vector时,一遍完成;判断时直接读取序列长度(出现次数)、计算在原数组中包含序列长度,比较即可。
当然,还可以只包含一个pair对,起始位置、另一个记录次数的map。
int n = nums.size();
map<int, vector<int>> eleSeqMap;
map<int, vector<int>>::iterator iter;
for(int i = 0; i < n; i++){
eleSeqMap[nums[i]].push_back(i);
}
int maxDegree = 0;
int minLength = 50000;
for(iter = eleSeqMap.begin(); iter != eleSeqMap.end(); iter++){
int tmp = (iter->second).back() - (iter->second).front() + 1;
if((iter->second).size() > maxDegree){
maxDegree = (iter->second).size();
minLength = tmp;
}
else if((iter->second).size() == maxDegree){
minLength = (minLength > tmp) ? tmp : minLength;
}
}
return minLength;
3、语言细节:对于map,迭代器是引用,需要用iter->first
这样的方式取;对于auto iter : map
,这是对象,需要用iter.first
的方式取。
int n = nums.size();
map<int, vector<int>> eleSeqMap;
for(int i = 0; i < n; i++)
eleSeqMap[nums[i]].push_back(i);
int maxDegree = 0;
int minLength = 50000;
for(auto iter : eleSeqMap){
vector<int> it = iter.second;
int tmp = it.back() - it.front() + 1;
if(maxDegree < it.size()){
maxDegree = it.size();
minLength = tmp;
}
else if(maxDegree == it.size()){
minLength = (minLength < tmp) ? minLength : tmp;
}
}
return minLength;