其他分享
首页 > 其他分享> > 【数组】力扣697:数组的度

【数组】力扣697:数组的度

作者:互联网

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


解题思路@负雪明烛

  1. 先求原数组的度
    求数组的度,本质还是求各个元素的出现次数,我们可以用 字典(哈希表)计数,字典的 key 是元素value 是该元素出现的次数。因此,字典中所有 value 的最大值就是数组的度 degree。
  2. 再求与原数组相同度的最短子数组

使用 left 和 right 分别保存每个元素在数组中第一次出现的位置和最后一次出现的位置;使用 counter 保存每个元素出现的次数。
数组的度 degree 等于 counter.values() 的最大值;
counter再次遍历:如果元素 k 出现的次数等于 degree,则找出元素 k 最后一次出现的位置 和 第一次出现的位置,计算两者之差+1,即为子数组长度。
对所有出现次数等于 degree 的子数组的最短长度,取 min。

class Solution:
    def findShortestSubArray(self, nums: List[int]) -> int:
        left, right = dict(), dict()
        counter = collections.Counter()
        for i, num in enumerate(nums):
            if num not in left:
                left[num] = i
            right[num] = i
            counter[num] += 1
        degree = max(counter.values())
        res = len(nums)
        for k, v in counter.items():
            if v == degree:
                res = min(res, right[k] - left[k] + 1)
        return res

时间复杂度:O(N),因为对数组遍历了一遍,对counter 遍历了两遍。
空间复杂度:O(N),因为 counter 在最坏情况下会跟 nums 的元素个数相等。

作者:fuxuemingzhu
链接:https://leetcode-cn.com/problems/degree-of-an-array/solution/xiang-xi-fen-xi-ti-yi-yu-si-lu-jian-ji-d-nvdy/

标签:元素,697,degree,nums,counter,力扣,次数,数组
来源: https://www.cnblogs.com/Jojo-L/p/16057978.html