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

方法一:
用hash table 统计所有number出现的次数,找出最高频率以及所有出现最高频率的数字,并依次计算他们在原数组中的左右边界,也就是第一次和最后一个出现的位置。

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        unordered_map<int, int> hash;
        int maxfreq = 0;
        for (int i = 0; i < nums.size(); i++) {
            hash[nums[i]]++;
            maxfreq = max(hash[nums[i]], maxfreq);
        }
        if (maxfreq == 1) return 1;

        vector<int> max;
        for (auto m : hash) {
            if (m.second == maxfreq) {
                max.push_back(m.first);
            }
        }

        int minlen = nums.size();

        for (int i = 0; i < max.size(); i++) {
            int cand = max[i];
            int minId = -1;
            int maxId = -1;
            int freq = maxfreq;
            for (int j = 0; j < nums.size() && freq > 0; j++) {
                if (nums[j] == cand) {
                    freq--;
                    if (minId == -1) minId = j;
                    if (freq == 0) maxId = j;
                }
            }
            if (maxId - minId + 1 < minlen) {
                minlen = maxId - minId + 1;
            }
        }
        return minlen;

    }
};

方法二:
用空间换时间,减少遍历的次数:
多建立两个hash table 存储每一个number的左右边界下标,遍历一遍数组,建立三个hash table.

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        unordered_map<int, int> hash_cnt;
        unordered_map<int, int> hash_left;
        unordered_map<int, int> hash_right;

        int maxfreq = 0;
        for (int i = 0; i < nums.size(); i++) {
            hash_cnt[nums[i]]++;
            maxfreq = max(hash_cnt[nums[i]], maxfreq);
            if (hash_left.find(nums[i]) == hash_left.end()) {
                hash_left[nums[i]] = i;
            }
            hash_right[nums[i]] = i;
        }
        if (maxfreq == 1) return 1;

        int minlen = nums.size();
        for (auto m : hash_cnt) {
            if (m.second == maxfreq) {
                minlen = min(minlen, hash_right[m.first] - hash_left[m.first] + 1);
            }
        }

        return minlen;

    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值