跳转至

697. 数组的度#

问题描述#

给定一个非空且只包含非负数的整数数组 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 范围内的整数。

解题思路#

用一个哈希表记录每个数出现的频次,另一个哈希表记录每个数第一次出现和最后一次出现的位置 \([\texttt{start},\texttt{end}]\)

最后的结果就是频次最大的数中最小的 \(\texttt{end} - \texttt{start} + 1\)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from typing import List
class Solution:
    def findShortestSubArray(self, nums: List[int]) -> int:
        count, pos = defaultdict(int), {}
        F = D = 0

        for i, x in enumerate(nums):
            if x not in pos: pos[x] = i
            count[x] += 1
            f, d = count[x], i - pos[x] + 1
            if f > F: F, D = f, d
            elif f == F and d < D: D = d

        return D
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        int F = 0, D = 0;
        unordered_map<int, int> count, pos;
        int n = nums.size();

        for (int i = 0; i < n; ++i) {
            if (!pos.count(nums[i])) pos[nums[i]] = i;
            int f = ++count[nums[i]], d = i - pos[nums[i]] + 1;
            if (f > F) F = f, D = d;
            else if (f == F && d < D) D = d;
        } 

        return D;
    }
};

时间复杂度\(\mathcal{O}(n)\)
空间复杂度\(\mathcal{O}(n)\)

返回顶部

在手机上阅读