zoukankan      html  css  js  c++  java
  • 697. 数组的度

    toc

    题目描述

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

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

    示例 1:

    输入:[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:

    输入:[1,2,2,3,1,4,2]
    输出:6

    提示:

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

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/degree-of-an-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思路

    题目稍微有点绕,多读几遍还是可以理解的
    根据题意,度即是元素出现的次数,求的度最大的数,从首次出现到最后一次出现的跨度,直接上代码吧

    class Solution {
    public:
        int findShortestSubArray(vector<int>& nums) {
            int iMaxDegree = 1;
            int iNumsSize = static_cast<int>(nums.size());
            std::unordered_map<int, int> unorderMapValueDegree;
            std::unordered_map<int, int> unorderMapValueLeft;
            std::unordered_map<int, int> unorderMapValueRight;
            std::unordered_map<int, int>::iterator itFind;
            for(int i = 0; i < iNumsSize; i++){
                int elem = nums[i];
                itFind = unorderMapValueDegree.find(elem);
                if(unorderMapValueDegree.end() == itFind){  //首次遇到,记录度与、元素最开始出现位置
                    unorderMapValueDegree.insert(std::make_pair(elem, 1));
                    unorderMapValueLeft.insert(std::make_pair(elem, i));
                    unorderMapValueRight.insert(std::make_pair(elem, i));
                }else{  //已经出现过的元素,记录出现的位置,循环结束后,只记录了最后出现的位置
                    itFind->second++;
                    unorderMapValueRight[elem] = i;   
                    iMaxDegree = max(iMaxDegree, itFind->second);     //记录下最大的度
                }
            }
    
            int iMinLen = iNumsSize;
            for(const auto& elem : unorderMapValueDegree){
                if(elem.second != iMaxDegree){
                    continue;
                }
                iMinLen = min(unorderMapValueRight[elem.first] - unorderMapValueLeft[elem.first] + 1, iMinLen);
            }    
            return iMinLen;
        }
    };

    优化

    上面的代码是利用map本身的key-value间的映射,将map换为数组,利用数组下标与值的对应关系,以空间换取时间的方式来提高性能

    const int VALUECOUNT = 50000;
    class Solution {
    public:
        int findShortestSubArray(vector<int>& nums) {
            int iMaxDegree = 1, iValue = 0;
            int iNumsSize = static_cast<int>(nums.size());
            //nums元素做下标,数组元素存储元素对应度、首次出现位置、最后一次出现位置
            int iArrayDegree[VALUECOUNT] = {0}, iArrayLeftIndex[VALUECOUNT], iArrayRightIndex[VALUECOUNT];
            for(auto& elem : iArrayLeftIndex){
                elem = -1;
            }
            for(int i = 0; i < iNumsSize; i++){
                iValue = nums[i];
                iArrayDegree[iValue]++;
                if(-1 == iArrayLeftIndex[iValue]){
                    iArrayLeftIndex[iValue] = i;
                }
                iArrayRightIndex[iValue] = i;   
                iMaxDegree = max(iMaxDegree, iArrayDegree[iValue]);
            }
    
            int iMinLen = iNumsSize;
            for(int i = 0; i < iNumsSize; i++){
                iValue = nums[i];
                if(iMaxDegree != iArrayDegree[iValue]){
                    continue;
                }
                iMinLen = min(iMinLen, iArrayRightIndex[iValue] - iArrayLeftIndex[iValue] + 1);
            }
            return iMinLen;
        }
    };


    vector相比数组更安全、更灵活,我首次优化的时候选了vector,结果搞了个负优化。于是换成数组,并且在栈上创建,换完之后过然速度飞升。





    原创不易,转载请注明出处,谢谢
  • 相关阅读:
    java(5)流程控制n阶乘各位和
    java(4)运算符
    java(3)
    java(2)
    java(1)
    语音识别,图片识别(1)
    java实现——005从尾到头打印链表
    java实现——004替换空格
    java实现——003二维数组中的查找
    java实现——035第一个只出现一次的字符
  • 原文地址:https://www.cnblogs.com/Keeping-Fit/p/14762914.html
Copyright © 2011-2022 走看看