数组的度

标签: 数组 哈希表

难度: Easy

给定一个非空且只包含非负数的整数数组 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 在 150,000 范围内。
  • nums[i] 是一个在 049,999 范围内的整数。

Submission

运行时间: 48 ms

内存: 18.2 MB

class Solution:
    def findShortestSubArray(self, nums: List[int]) -> int:
        mp = dict()

        for i, num in enumerate(nums):
            if num in mp:
                mp[num][0] += 1
                mp[num][2] = i
            else:
                mp[num] = [1, i, i]

        maxNum = minLen = 0
        for count, left, right in mp.values():
            if maxNum < count:
                maxNum = count
                minLen = right - left + 1
            elif maxNum == count:
                if minLen > (span := right - left + 1):
                    minLen = span

        return minLen


Explain

该题解使用哈希表来统计每个元素的出现次数、第一次出现的位置和最后一次出现的位置。遍历数组,对于每个元素,如果已经在哈希表中存在,则更新出现次数和最后一次出现的位置;否则,在哈希表中添加该元素的信息。接下来,遍历哈希表中的每个元素,找到出现次数最多的元素,并计算该元素第一次出现和最后一次出现之间的子数组长度,更新最短连续子数组的长度。最后返回最短连续子数组的长度。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def findShortestSubArray(self, nums: List[int]) -> int:
        mp = dict()

        # 遍历数组,统计每个元素的出现次数、第一次出现的位置和最后一次出现的位置
        for i, num in enumerate(nums):
            if num in mp:
                mp[num][0] += 1  # 更新出现次数
                mp[num][2] = i   # 更新最后一次出现的位置
            else:
                mp[num] = [1, i, i]  # 添加新元素的信息

        maxNum = minLen = 0
        # 遍历哈希表,找到出现次数最多的元素并计算最短连续子数组的长度
        for count, left, right in mp.values():
            if maxNum < count:
                maxNum = count
                minLen = right - left + 1
            elif maxNum == count:
                if minLen > (span := right - left + 1):
                    minLen = span

        return minLen

Explore

在遍历数组的过程中,每次遇到一个元素,都会检查该元素是否已存在于哈希表中。如果存在,就更新该元素的出现次数和最后一次出现的位置;如果不存在,则在哈希表中创建一个新的条目,并初始化出现次数和第一次出现的位置。这种方法确保了每次元素出现时,其统计数据都被即时和准确地更新。

追踪每个元素的第一次和最后一次出现位置是为了能够计算出具有相同度的所有元素中,最短的连续子数组的长度。这个长度是由第一次出现的位置到最后一次出现的位置的距离决定的。只有记录了这两个位置,我们才能准确计算出满足条件的最短子数组长度。

是的,可能存在多个元素具有相同的最高度,但它们的第一次和最后一次出现的位置不同,因此导致计算出的子数组长度不同。在这种情况下,我们需要比较所有具有相同度的元素的子数组长度,并选择最短的一个作为结果。

如果数组中所有元素相同,那么这个元素的度等于数组的长度,且第一次和最后一次出现的位置分别是数组的开始和结束位置。在这种情况下,最短连续子数组即为整个数组本身。算法在这种情况下依然有效,不需要特别的处理方式,直接返回整个数组的长度即可。