题目地址(632. 最小区间)

题目地址(632. 最小区间)

题目描述

你有 k 个 非递减排列 的整数列表。找到一个 最小 区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

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

 

示例 1:

输入:nums = [[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] 中。


示例 2:

输入:nums = [[1,2,3],[1,2,3],[1,2,3]]
输出:[1,1]


 

提示:

nums.length == k
1 <= k <= 3500
1 <= nums[i].length <= 50
-105 <= nums[i][j] <= 105
nums[i] 按非递减顺序排列

 

前置知识

公司

  • 暂无

思路

关键点

代码

  • 语言支持:Python3

Python3 Code:


class Solution:
    def smallestRange(self, nums: List[List[int]]) -> List[int]:
        # 采用多路回归的方式
        l,r = -float('inf'),float('inf')
        # 构建小根堆
        h = [(row[0],i,0) for i,row in enumerate(nums)]
        heapq.heapify(h)
        max_v = max([row[0] for row in nums])

        # 思路:
        """
        采用多路归并的思想,首先取二维数组的第一列元素,记住每个元素的行、列,组成一个小根堆,从而可以维护一个小区间
        这个区间的最小值就是堆顶,最大值可以用一个变量表示
        现在考虑如何进行多路归并,基本思想就是取出区间最小值后,在这一列继续向下取值

        为什么选择在最小值后面继续取值?
        前提:二维数字的每一行都是非递减的
        那么在已经有一个区间的前提下,移动左区间是比移动其他区间中的任何值更加能保证区间可以hold所有值

        """
        while True:
            min_v, row, col = heapq.heappop(h)

            if max_v - min_v < r - l:
                l,r = min_v, max_v
            
            if col == len(nums[row]) - 1: return l,r 

            heapq.heappush(h,(nums[row][col+1],row,col+1))
            max_v = max(nums[row][col+1],max_v)


复杂度分析

令 n 为数组长度。

  • 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度: O ( n ) O(n) O(n)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值