思路
优化
题目描述
给定一个非空且只包含非负数的整数数组 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
提示:
nums.length 在1到 50,000 区间范围内。
nums[i] 是一个在 0 到 49,999 范围内的整数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/degree-of-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
题目稍微有点绕,多读几遍还是可以理解的
根据题意,度即是元素出现的次数,求的度最大的数,从首次出现到最后一次出现的跨度,直接上代码吧
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
int iMaxDegree = 1;
int iNumsSize = static_cast<int>(nums.size());
std::unordered_map<int, int> unorderMapValueDegree;
std::unordered_map<int, int> unorderMapValueLeft;
std::unordered_map<int, int> unorderMapValueRight;
std::unordered_map<int, int>::iterator itFind;
for(int i = 0; i < iNumsSize; i++){
int elem = nums[i];
itFind = unorderMapValueDegree.find(elem);
if(unorderMapValueDegree.end() == itFind){ //首次遇到,记录度与、元素最开始出现位置
unorderMapValueDegree.insert(std::make_pair(elem, 1));
unorderMapValueLeft.insert(std::make_pair(elem, i));
unorderMapValueRight.insert(std::make_pair(elem, i));
}else{ //已经出现过的元素,记录出现的位置,循环结束后,只记录了最后出现的位置
itFind->second++;
unorderMapValueRight[elem] = i;
iMaxDegree = max(iMaxDegree, itFind->second); //记录下最大的度
}
}
int iMinLen = iNumsSize;
for(const auto& elem : unorderMapValueDegree){
if(elem.second != iMaxDegree){
continue;
}
iMinLen = min(unorderMapValueRight[elem.first] - unorderMapValueLeft[elem.first] + 1, iMinLen);
}
return iMinLen;
}
};
优化
上面的代码是利用map本身的key-value间的映射,将map换为数组,利用数组下标与值的对应关系,以空间换取时间的方式来提高性能
const int VALUECOUNT = 50000;
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
int iMaxDegree = 1, iValue = 0;
int iNumsSize = static_cast<int>(nums.size());
//nums元素做下标,数组元素存储元素对应度、首次出现位置、最后一次出现位置
int iArrayDegree[VALUECOUNT] = {0}, iArrayLeftIndex[VALUECOUNT], iArrayRightIndex[VALUECOUNT];
for(auto& elem : iArrayLeftIndex){
elem = -1;
}
for(int i = 0; i < iNumsSize; i++){
iValue = nums[i];
iArrayDegree[iValue]++;
if(-1 == iArrayLeftIndex[iValue]){
iArrayLeftIndex[iValue] = i;
}
iArrayRightIndex[iValue] = i;
iMaxDegree = max(iMaxDegree, iArrayDegree[iValue]);
}
int iMinLen = iNumsSize;
for(int i = 0; i < iNumsSize; i++){
iValue = nums[i];
if(iMaxDegree != iArrayDegree[iValue]){
continue;
}
iMinLen = min(iMinLen, iArrayRightIndex[iValue] - iArrayLeftIndex[iValue] + 1);
}
return iMinLen;
}
};
vector相比数组更安全、更灵活,我首次优化的时候选了vector,结果搞了个负优化。于是换成数组,并且在栈上创建,换完之后过然速度飞升。
来自为知笔记(Wiz)