LeetCode每日一题(632. Smallest Range Covering Elements from K Lists)

这道题目要求在k个非递减有序整数列表中找到最小范围,包含每个列表至少一个元素。例如,对于输入[[4,10,15,24,26],[0,9,12,20],[5,18,22,30]],输出为[20,24]。解决方案采用类似归并排序的方法,使用最小堆来维护答案中的数字,不断更新最小值和可能的最大值。" 126082500,12582789,DBeaver连接MySQL数据库及解决Connection refused错误,"['数据库管理', '前端开发', '后端开发']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You have k lists of sorted integers in non-decreasing order. Find the smallest range that includes at least one number from each of the k lists.

We define the range [a, b] is smaller than range [c, d] if b - a < d - c or a < c if b - a == d - c.

Example 1:

Input: nums = [[4,10,15,24,26],[0,9,12,20],[5,18,22,30]]
Output: [20,24]

Explanation:
List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
List 2: [0, 9, 12, 20], 20 is in range [20,24].
List 3: [5, 18, 22, 30], 22 is in range [20,24].

Example 2:

Input: nums = [[1,2,3],[1,2,3],[1,2,3]]
Output: [1,1]

Constraints:

  • nums.length == k
  • 1 <= k <= 3500
  • 1 <= nums[i].length <= 50
  • -105 <= nums[i][j] <= 105
  • nums[i] is sorted in non-decreasing order.

整体来说是用 merge sort 的方式

用一个 min heap 来维护最终答案中所有的数字, 每次从 heap 中 pop 出最小值, 将该数字所在 list 中的下一个数字 push 进 heap 中, 此时 range 中的最小值是 heap 中 top 的值, 最大值有可能是刚刚 push 进去的那个值, 我们只需要用原有的最大值与该值进行比较即可。



use std::cmp::Reverse;
use std::collections::BinaryHeap;

impl Solution {
    pub fn smallest_range(nums: Vec<Vec<i32>>) -> Vec<i32> {
        let mut ans;
        let mut min = i32::MAX;
        let mut max = i32::MIN;
        let mut heap = BinaryHeap::new();
        let mut pointers = vec![0; nums.len()];
        for (i, row) in nums.iter().enumerate() {
            min = min.min(row[0]);
            max = max.max(row[0]);
            heap.push(Reverse((row[0], i)));
        }
        ans = vec![min, max];
        loop {
            let Reverse((_, i)) = heap.pop().unwrap();
            pointers[i] += 1;
            if pointers[i] == nums[i].len() {
                break;
            }
            heap.push(Reverse((nums[i][pointers[i]], i)));
            min = heap.peek().unwrap().0 .0;
            max = max.max(nums[i][pointers[i]]);
            if max - min < ans[1] - ans[0] {
                ans = vec![min, max];
            }
        }
        ans
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值