力扣每日一题-第45天-697. 数组的度

该博客讨论了一种算法问题,即在非空且非负整数数组中找到度最大的元素(出现次数最多的元素)并找出这些元素形成的最短连续子数组。博主提出了两种解决方案,一种使用哈希表记录元素频率,另一种优化方案通过维护一个哈希映射来存储元素及其位置,以找到最短子数组。虽然第一种方法在力扣上因数组越界而失败,但思路正确。最后,博主给出了优化后的代码实现。
摘要由CSDN通过智能技术生成

2022.8.1今天你刷题了吗?


题目:

给定一个非空且只包含非负数的整数数组 nums,数组的 度 的定义是指数组里任一元素出现频数的最大值。

你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。

分析:

给定一个数组,需要找到里面度最大的元素,然后求出这些元素中能够构成最短连续子数组的大小,情况如下:

【1,2,3,3,1】度最大=2,且包括元素1,3,但是最短连续子数组是3,其长度为2

【1,2,1,3,1】度最大=3,为元素1,最短子数组长度为3.

思路:利用一个哈希表,记录元素,然后找到里面最大的度以及度对应的元素有哪些,然后分别对这些元素进行遍历,求出它们的最短子数组(但是在力扣中出错了,因为数组大小越界被限制),但是思路没问题。

解析:

1.暴力法(有问题)

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        unordered_map<int, int>map;
        vector<int>vec;
        int res = 0;
        int ans = 0;
        int q = 0;
        int w = 0;
        int e = 0;
        int r = 100000;
        for (auto num : nums)
        {
            map[num]++;
            res = max(map[num], res);//找到了度的大小
        }
        e = res;
        for (std::unordered_map<int, int>::iterator it = map.begin(); it != map.end(); it++)
        {
            if (it->second == res)
            {
                ans = it->first;
                vec.push_back(ans);//插入度最大的元素,可能有多个
            }
        }
        for (int j=0;j<vec.size();j++)
        {

            for (int i = 0; i < nums.size(); i++)
            {
                if (nums[i] == vec[j] && e == res)
                {
                    q = i;
                    e--;
                }
                else if (nums[i] == vec[j] && e == 1)
                {
                    w = i;
                }
                else if (nums[i] == vec[j] && e != res && e != 1)
                {
                    e--;
                }
                else if (e == 0)
                {
                    r = q+1;
                    return r;
                }
            }
            e = res;
            r = min(r, w - q + 1);
        }
        return r;
    }
};

2.优化

在求度以及对应元素时,利用一个vector容器一次型存放,这样方便后面的计算

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        unordered_map<int, vector<int>> mp;
        int n = nums.size();
        for (int i = 0; i < n; i++) {
            if (mp.count(nums[i])) {
                mp[nums[i]][0]++;
                mp[nums[i]][2] = i;
            }
            else {
                mp[nums[i]] = { 1, i, i };
            }
        }
        int maxNum = 0, minLen = 0;
        for (auto& [_, vec] : mp) {
            if (maxNum < vec[0]) {
                maxNum = vec[0];
                minLen = vec[2] - vec[1] + 1;
            }
            else if (maxNum == vec[0]) {
                if (minLen > vec[2] - vec[1] + 1) {
                    minLen = vec[2] - vec[1] + 1;
                }
            }
        }
        return minLen;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值