[python]leetcode(632). Smallest Range

problem

You have k lists of sorted integers in ascending 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.

solution

就是一个问题化简的过程:
思考方式:
第一步:首先把这个问题考虑为从所有的元素中选出两个的且每个列表中的元素都有在这个区间中的,所有元素的两两组合,即 O(n2) 种组合

第二步:分别以所有的元素为区间起始节点,找到它们对应的长度最小的区间,最后从中选取最短的那个 O(n) 种组合。

第三步:如何找到符合条件的最短区间?上面的组合虽然有 O(n) 种,但是如果暴力搜索的话,即对每一个元素都从整体排序的列表找搜寻代价要很大。所以我们在这里进行优化。

建立一个数组arr, 初始时里面存储每个数组的最小值,那么此时arr中的最大值对应的就是以最小值为起始的、符合要求的最短区间(因为需要包含所有的数组中的至少一个元素,如果有比现在还短的区间的话,那么一定未包含最大元素所在区间的元素)

更新方式:把最小值所在的数组指针向前移动一个元素,继续使用上面的方法确定第二小元素所对应的最短区间。

第四步:在上面的arr中其实我们每次只需要获取最大和最小元素,所以可以使用优先队列来存储,最小的元素我们可以直接获得,最大的只要每次更新元素时进行一次比较就行了。

抽象数据类型:接口描述(元素 + 操作),例如优先队列:

  1. 插入带优先级的元素(insert_with_priority)
  2. 取出具有最高优先级的元素(pull_highest_priority_element)
  3. 查看最高优先级的元素(peek):O(1) 时间复杂度

数据结构:具体实现,优先队列可以使用最基础的数组实现,每次查找都进行一次比较,或是使用堆实现。

总结

要先简化算法(第一步到第三步),然后根据算法中要求选择合适的数据结构(第四步)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值