697. Degree of an Array(python+cpp)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21275321/article/details/83111262

题目:

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;
    }
};

总结:
找到一个数字在数组中最开始出现的位置和最后出现的位置~~很重要。

猜你喜欢

转载自blog.csdn.net/qq_21275321/article/details/83111262