题目:
Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements.
Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums.
Example 1:Input: [1, 2, 2, 3, 1] Output: 2 Explanation: The inputarray 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 is2. So return 2.
Example 2:
Input: [1,2,2,3,1,4,2] Output: 6
Note:
nums.length
will be between 1 and 50,000.
nums[i]
will be an integerbetween 0 and 49,999.
解释:
找到nums
最短的subarray使得该subarray和nums
有相同的degree,degree表示数组中众数的个数。
暴力解法:找出这个list的所有子序列,在判断每个子序列的degree是否和这个list的degree相同,但是TLE。
找出每一个可能是出现此处==degree的数num
,那么最左边的num
和最右边的num
之间的长度的 最小值,就是最终的答案。
python代码:
class Solution(object):
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
set_nums=set(nums)
if len(nums)==len(set_nums):
return 1
degree =max([nums.count(x) for x in set_nums])
maybe=[]
for x in set_nums:
if nums.count(x)==degree:
maybe.append(x)
len_m=100000
for m in maybe:
temp=(len(nums)-nums[::-1].index(m))-nums.index(m)
len_m=min(len_m,temp)
return len_m
用字典的方法,实际上也是为了存储某个值的最开始出现的index和最后出现的index。
学会用字典和setdefault()
函数,如果键不存在在字典中则将键值对写入,如果存在则不进行更新。
get()
函数返回指定键的值,如果值不在字典中返回默认值。
python代码:
class Solution(object):
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
set_nums=set(nums)
if len(set_nums)==len(nums):
return 1
degree =max([nums.count(x) for x in set_nums])
left,right={},{}
for index,val in enumerate(nums):
left.setdefault(val,index)
right[val]=index
return min((right[val]-left[val]+1 for val in set_nums if nums.count(val)==degree))
c++代码:
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
if(nums.size()==0)
return 0;
set<int> _set(nums.begin(),nums.end());
if(nums.size()==_set.size())
return 1;
int degree=0;
for(auto num:_set)
{ int _count=count(nums.begin(),nums.end(),num);
degree=max(degree,_count);
}
vector<int>maybe;
for (auto num:_set)
{
if (count(nums.begin(),nums.end(),num)==degree)
maybe.push_back(num);
}
vector<int>reverse_nums(nums.begin(),nums.end());
reverse(reverse_nums.begin(),reverse_nums.end());
int min_len=INT_MAX;
int n=nums.size();
for(auto num:maybe)
{ int index1=n-(find(reverse_nums.begin(),reverse_nums.end(),num)-reverse_nums.begin());
int index2=find(nums.begin(),nums.end(),num)-nums.begin();
min_len=min(min_len,index1-index2);
}
return min_len;
}
};
总结:
找到一个数字在数组中最开始出现的位置和最后出现的位置~~很重要。