解法
不会,搬运一下官方解答
需要利用升序和只有一个数字的交集的特征。
首先,可以枚举最后交集的数字,它将是一个k维向量,可以用一个k维的指针表示,产生这个的区间就是这个向量的最小值和最大值
当然,如果傻傻地枚举那不是得有k层循环了?
这时候需要利用升序的特点。
假设目前枚举到一个k维向量,它有一个区间[A,B]
,那么我们想要缩小区间有两个办法,一是减小最大值,二是增大最小值。
- 如果要减小最大值,那么最大值在的那一列的指针需要前移一位
- 如果要增加最小值,那么最小值在的那一列的指针需要后移一位
假如我们从每一行的第一个数开始从左向右扫描,那么就只有增大最小值这一个选择;假如从右向左扫,也只有减小最大值这一个选择
用堆可以加快查找
class Solution(object):
def smallestRange(self, nums):
"""
:type nums: List[List[int]]
:rtype: List[int]
"""
from heapq import heappush,heappop
heap = []
n = len(nums)
INF = 10**5+1
maxval = -INF
for i in xrange(n):
maxval = max(nums[i][0],maxval)
heappush(heap,(nums[i][0],i,0))
def less(a,b):
da = a[1]-a[0]
db = b[1]-b[0]
if da==db:
return a[0]<b[0]
return da<db
ans = [-INF,INF]
while True:
v,i,j = heappop(heap)
t = [v,maxval]
if less(t,ans):
ans = t
j += 1
if j>=len(nums[i]):break
if len(heap)==0:
maxval = -INF
maxval = max(maxval,nums[i][j])
heappush(heap,(nums[i][j],i,j))
return ans