• [LeetCode] 697. Degree of an Array 数组的度


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

    Note:

    • nums.length will be between 1 and 50,000.
    • nums[i] will be an integer between 0 and 49,999.

    给一个非空非负整数的数组,找出和整个数组最大度相同的最短的子数组。度是一个数组里数字出现频率的最大值。

    解法:首先要知道整个数组的度,可用哈希表进行统计。度最大的子数组里,首尾数字都是这个度的数字时,子数组是最短的,在用一个哈希表保存,某一个数字第一次出现的index和最后一次出现的index。还要注意度相同的数字可能不只一个所以要求这几个数字中最短的。

    Java:

    public static class Solution2 {
        public int findShortestSubArray(int[] nums) {
            Map<Integer, Integer> count = new HashMap<>();
            Map<Integer, Integer> left = new HashMap<>();
            Map<Integer, Integer> right = new HashMap<>();
    
            for (int i = 0; i < nums.length; i++) {
                count.put(nums[i], count.getOrDefault(nums[i], 0) + 1);
                if (!left.containsKey(nums[i])) {
                    left.put(nums[i], i);
                }
                right.put(nums[i], i);
            }
    
            int result = nums.length;
            int degree = Collections.max(count.values());
            for (int num : count.keySet()) {
                if (count.get(num) == degree) {
                    result = Math.min(result, right.get(num) - left.get(num) + 1);
                }
            }
            return result;
        }
    }
    

    Java:

    public int findShortestSubArray(int[] nums) {
            if (nums.length == 0 || nums == null) return 0;
            Map<Integer, int[]> map = new HashMap<>();
            for (int i = 0; i < nums.length; i++){
               if (!map.containsKey(nums[i])){
                   map.put(nums[i], new int[]{1, i, i});  // the first element in array is degree, second is first index of this key, third is last index of this key
               } else {
                   int[] temp = map.get(nums[i]);
                   temp[0]++;
                   temp[2] = i;
               }
            }
            int degree = Integer.MIN_VALUE, res = Integer.MAX_VALUE;
            for (int[] value : map.values()){
                if (value[0] > degree){
                    degree = value[0];
                    res = value[2] - value[1] + 1;
                } else if (value[0] == degree){
                    res = Math.min( value[2] - value[1] + 1, res);
                } 
            }
            return res;
        }  

    Python:

    class Solution(object):
        def findShortestSubArray(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            counts = collections.Counter(nums)
            left, right = {}, {}
            for i, num in enumerate(nums):
                left.setdefault(num, i)
                right[num] = i
            degree = max(counts.values())
            return min(right[num]-left[num]+1 
                       for num in counts.keys() 
                       if counts[num] == degree)
    

    Python: wo

    class Solution(object):
        def findShortestSubArray(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            if len(nums) < 2:
                return len(nums)
            
            degree = collections.Counter()
            index = collections.defaultdict(list)
            max_degree = 0
            max_num = []
            for k, v in enumerate(nums):
                degree[v] += 1
                if degree[v] > max_degree:
                    max_degree = degree[v]
                    max_num = []
                    max_num.append(v)
                elif degree[v] == max_degree:
                    max_num.append(v)
                index[v].append(k)
    
            min_dis = float('inf')
            for v in max_num:
                i, j = index[v][0], index[v][-1]
                min_dis = min(min_dis, j - i + 1)
                
            return min_dis  
    

    C++:

    class Solution {
    public:
        int findShortestSubArray(vector<int>& nums) {
            int n = nums.size(), res = INT_MAX, degree = 0;
            unordered_map<int, int> m;
            unordered_map<int, pair<int, int>> pos;
            for (int i = 0; i < nums.size(); ++i) {
                if (++m[nums[i]] == 1) {
                    pos[nums[i]] = {i, i};
                } else {
                    pos[nums[i]].second = i;
                }
                degree = max(degree, m[nums[i]]);
            }
            for (auto a : m) {
                if (degree == a.second) {
                    res = min(res, pos[a.first].second - pos[a.first].first + 1);
                }
            }
            return res;
        }
    };
    

    C++:

    class Solution {
    public:
        int findShortestSubArray(vector<int>& nums) {
            int n = nums.size(), res = INT_MAX, degree = 0;
            unordered_map<int, int> m, startIdx;
            for (int i = 0; i < n; ++i) {
                ++m[nums[i]];
                if (!startIdx.count(nums[i])) startIdx[nums[i]] = i;
                if (m[nums[i]] == degree) {
                    res = min(res, i - startIdx[nums[i]] + 1);
                } else if (m[nums[i]] > degree) {
                    res = i - startIdx[nums[i]] + 1;
                    degree = m[nums[i]];
                }
            }
            return res;
        }
    };
    

      

      

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    浏览器中跨域创建cookie的问题
    tomcat域名问题
    Hibernate saveOrUpdate方法到底是怎么执行的?
    Ajax提交后台中文乱码问题
    允许浏览器跨域访问web服务端的解决方案
    IntelliJ 有的时候移动滚动条后会自动回到光标所在位置的解决方法
    线程池
    Jackson转换对象为json的时候报java.lang.stackoverflowerror
    虚拟内存
    Linux下JDK安装笔记
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9607785.html
Copyright © 2020-2023  润新知