【leetcode】数组的度 c++

题目描述:

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

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

示例 1:

输入:nums = [1,2,2,3,1]
输出:2
解释:
输入数组的度是 2 ,因为元素 1 和 2 的出现频数最大,均为 2 。
连续子数组里面拥有相同度的有如下所示:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
最短连续子数组 [2, 2] 的长度为 2 ,所以返回 2 。

示例2:

输入:nums = [1,2,2,3,1,4,2]
输出:6
解释:
数组的度是 3 ,因为元素 2 重复出现 3 次。
所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6 。

提示:

nums.length 在 1 到 50,000 范围内。
nums[i] 是一个在 0 到 49,999 范围内的整数。

代码:

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        int n=nums.size(),max=0;
        int minlen=n;
        map<int,int> min_index,max_index,distance;
        for(int i=0;i<n;i++){
            if(min_index[nums[i]]==0){
                min_index[nums[i]]=i+1; //+1避免第一个元素下标为0,记录了但检测不出来。
            }
            else continue;
        }
        for(int i=n-1;i>=0;i--){
            if(max_index[nums[i]]==0)
            max_index[nums[i]]=i+1;//+1避免第一个元素下标为0,记录了但检测不出来。
        }
        for(int i=0;i<n;i++){
            distance[nums[i]]=max_index[nums[i]]-min_index[nums[i]]+1;
            if(distance[nums[i]]==0)distance[nums[i]]=1; //只出现一次的数字,长度不为0,应为1
        }
        map<int,int> f;
        for(int i=0;i<n;i++){
            f[nums[i]]++;
            if(f[nums[i]]>max)max=f[nums[i]];
        }
        for(int i=0;i<n;i++){
            if(f[nums[i]]==max){
                if(distance[nums[i]]<minlen)minlen=distance[nums[i]];
            }
        }
        return minlen;
    }
};

此题要求原数组中,包含出现次数最多的数字的最短连续子数组。

要想最短,只需要子数组的两头均为度数最大的数字(出现次数最多的数字),而左端和右端再没有其他数字。

连续是指求相同数字间的最远距离。

原问题转化为,求出重复出现次数最多且距离最远的数字间的长度

例如,【1,2,2,3,1,3,6】中:

1出现2次,2出现2次,3出现2次,6出现1次;
1和1之间的最远距离为6,2和2间的距离为2,3和3之间的距离为3;
所以度数最大的最长连续子数组长度为6。

注意理解题意,转化问题。(”最大连续子数组长度“转化为相同数字间的最大距离)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值