leetcode 632. 最小区间

632. 最小区间
你有 k 个升序排列的整数数组。找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。

示例 1:

输入:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
输出: [20,24]
解释:
列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。
列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。
列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。
注意:

给定的列表可能包含重复元素,所以在这里升序表示 >= 。
1 <= k <= 3500
-105 <= 元素的值 <= 105
对于使用Java的用户,请注意传入类型已修改为List<List>。重置代码模板后可以看到这项改动。


这道题目我首先想到的就是76. 最小覆盖子串这道题的解法,使用滑动窗口进行求最小包含区间。但是这道题目在原始的数据中是多个列表的存在形式。所以在确定每一个列表都有一个值得时候,需要对每一个列表增加一个列表属性的标签。

增加属性标签就是将一维的列表增至二维,第一维为属性,第二维为数值。再将每一组二维数据合并在一起,具体的实现代码为:

    for i in range(k):#k个列表
        res += [[i, item] for item in nums[i]]#对每一个列表的内的数组增维

增维之后我们再对数据的第二维进行一个递增排序,这样就和之前的76题类似了。

  1. 建立两个字典,一个为目标需要的字典need,包含了key,val。key:需要的标签名称,val:该类标签需要的个数。由于本次需要所有的k个列表内的值,都出现依次,所以可以直接复制,key = i , val = 1。
  2. 建立win窗口字典,包含的是窗口内的标签种类以及数量。当win满足need的最低要求时,可以加入输出。这里的最低要求使用的是valid表示,每当win[i] 增加一个之后,win[i] == 1,的时候,valid就会加一,之后win[i]再继续增加,超过一,虽然会继续计数,但是valid值是不会增加,因为已经满足最小匹配了。
  3. 当valid 的个数等于 k的个数的时候,说明这个区间内是满足至少每个列表有一个数的。为了求一个最优的区间,这个时候需要缩小左边界。缩小左边界的时候,如果最左边对应的字典值win[ i ] == 1,那么在缩小的过程中间,win[ i ] 就会变成0,此时的valid个数也会减一。
  4. 每次得到valid == k的时候,我们要计算一下此时的区间长度,每次更新找到一个最优的区间长度。
class Solution:
    def smallestRange(self, nums: List[List[int
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值