打卡力扣题目十二

简介: 打卡力扣题目十二

关于 ARTS 的释义 —— 每周完成一个 ARTS:

● Algorithm: 每周至少做一个 LeetCode 的算法题

● Review: 阅读并点评至少一篇英文技术文章

● Tips: 学习至少一个技术技巧

● Share: 分享一篇有观点和思考的技术文章


希望通过此次活动能聚集一波热爱技术的人,延续好奇、探索、实践、分享的精神。

 

一、问题

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

nums[i] 是一个在 0 到 49,999 范围内的整数。


二、解题方法一

def findShortestSubArray(nums):
    # 统计每个数字出现的频数和第一次出现的位置
    count = {}
    first_occurrence = {}
    max_degree = 0
    for i, num in enumerate(nums):
        if num not in count:
            count[num] = 1
            first_occurrence[num] = i
        else:
            count[num] += 1
        # 更新最大度
        if count[num] > max_degree:
            max_degree = count[num]
    # 找到与最大度相同的数字的最短连续子数组长度
    min_length = float('inf')
    for num in count:
        if count[num] == max_degree:
            length = i - first_occurrence[num] + 1
            if length < min_length:
                min_length = length
    return min_length

这段代码实现了一个函数 `findShortestSubArray`,用于找到给定数组中,出现次数最多的数字所对应的最短连续子数组的长度。


具体实现过程如下:


 1. 首先定义了三个字典变量:`count`、`first_occurrence` 和 `max_degree`,分别用于统计每个数字出现的频数、第一次出现的位置以及最大度(即出现次数最多的数字的出现次数)。


 2. 然后遍历输入的数组 `nums`,对于每个数字 `num`,如果它不在 `count` 中,则将其添加到 `count` 中并记录其第一次出现的位置;否则,将其出现次数加一。同时,如果当前数字的出现次数大于之前的最大度,则更新最大度。


 3. 接着遍历 `count` 中的每个数字,如果某个数字的出现次数等于最大度,则计算该数字所对应的最短连续子数组的长度。具体来说,首先计算该数字最后一次出现的位置与第一次出现的位置之差加一,即为该数字所对应的子数组的长度;然后将这个长度与之前计算得到的最短连续子数组长度进行比较,取较小值作为新的最短连续子数组长度。


 4. 最后返回计算得到的最短连续子数组长度。


需要注意的是,在计算最短连续子数组长度时,需要使用变量 `i` 来记录当前遍历到的位置,因此在循环开始前需要先初始化 `i` 为 0。


三、解题方法二

def findShortestSubArray(nums):
# 使用哈希表记录每个数字出现的次数和位置
count = {}
for i, num in enumerate(nums):
if num not in count:
count[num] = [1, i]
else:
count[num][0] += 1
# 按照出现次数从大到小排序
sorted_count = sorted(count.items(), key=lambda x: x[1][0], reverse=True)
# 找到出现次数最多的数字所对应的最短连续子数组长度
max_degree = sorted_count[0][1][0]
min_length = float('inf')
for num, (degree, _) in enumerate(sorted_count):
    if degree == max_degree:
        length = nums[_] + nums[_ + degree] + 1
        if length < min_length:
            min_length = length
return min_length

这个实现方式与之前的实现方式类似,但是使用了哈希表来记录每个数字出现的次数和位置,避免了在遍历数组时多次计算某个数字的出现次数。同时,将哈希表中的元素按照出现次数从大到小排序,可以减少后续查找的复杂度。最后,通过遍历排序后的哈希表,找到出现次数最多的数字所对应的最短连续子数组长度。


相关文章
|
4天前
|
算法
LeetCode第12题目整数转罗马数字
该文章介绍了 LeetCode 第 12 题整数转罗马数字的解法,通过使用 TreeMap 按照整数从大到小排序,先使用大的罗马数字表示整数,再用小的,核心是先表示完大的罗马数字,想通此点该题较简单。
LeetCode第12题目整数转罗马数字
|
11天前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
27 6
|
4天前
|
算法
LeetCode第13题目罗马数字转整数
该文章介绍了 LeetCode 第 13 题罗马数字转整数的解法,通过从大到小解析罗马数字,根据罗马数字的特点,按照从大到小的顺序匹配罗马数字和整数的关系,从而解决该问题,同时强调要注意观察题目考查的知识点特征。
|
2月前
|
C语言
详解Leetcode中关于malloc模拟开辟二维数组问题,涉及二维数组的题目所给函数中的各个参数的解读
详解Leetcode中关于malloc模拟开辟二维数组问题,涉及二维数组的题目所给函数中的各个参数的解读
14 1
|
1月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
2月前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
2月前
|
容器
【LeetCode刷题】栈和队列题目练习~
【LeetCode刷题】栈和队列题目练习~
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总(4)
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总
|
2月前
|
存储 算法
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总(1)
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总
|
2月前
|
算法
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成