【leetcode】697. 数组的度(degree-of-an-array)(模拟)[简单]

链接

https://leetcode-cn.com/problems/degree-of-an-array/

耗时

解题:1 h 29 min
题解:13 min

题意

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

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

提示:

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

思路

题意相当于是想找到频数最大的元素在数组中的首位元素的位置,长度就是首位元素位置的差。因为频数最大的元素可能不止一个,所以有题意是:返回数组中频数最大的元素中最小的长度。

定义一个结构体(包含元素的 值 和 位置),对这个结构体按元素值排序,元素值相同按位置排序。然后遍历排序后的结构体数组,相同的元素值都是挨着的,计数频率很方便,并且找到相同元素值得头尾,把他们对应的位置减一下就可以得到长度。

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

AC代码

class Solution {
    
    
public:
    struct node {
    
    
        int val;
        int pos;
        bool operator < (const node d) const {
    
    
            return (val==d.val)?(pos<d.pos):(val<d.val);
        }
    };
    int findShortestSubArray(vector<int>& nums) {
    
    
        vector<node> valpos;
        int n = nums.size();
        for(int i = 0; i < n; ++i) {
    
    
            valpos.push_back((node){
    
    nums[i], i});
        }
        sort(valpos.begin(), valpos.end());
        
        int maxfreq = 0, minlen = 0;
        int freq = 1, l = valpos[0].pos;
        for(int i = 1; i <= n; ++i) {
    
    
            if(i == n || valpos[i].val != valpos[i-1].val) {
    
    
                if(freq > maxfreq) {
    
    
                    maxfreq = freq;
                    minlen = valpos[i-1].pos-l+1;
                }
                else if(freq == maxfreq) {
    
    
                    minlen = min(minlen, valpos[i-1].pos-l+1);
                }
                freq = 0;
                if(i < n) l = valpos[i].pos;
            }
            freq++;
        }
        
        return minlen;
    }
};

猜你喜欢

转载自blog.csdn.net/Krone_/article/details/113884674