Leetcode: 632. Smallest Range Covering Elements from K Lists

Description

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.

Example

Input: [[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].

Note

The given list may contain duplicates, so ascending order means >= here.
1 <= k <= 3500
-105 <= value of elements <= 105.

分析

因为本题被归类为 双头指针,所以一开始一直在往双头指针上靠。希望可以找到一个答案。但是一直想不出来一个可行解。
准备用二分搜索+滑动窗口(即将所有的 llist 合并为 一个 超大的 list,同时记录每个元素的下的有多少哥元素。。。。)
后面该用 heapq,保证 heapq 一直是 k list 个元素,且能保证 最大和最小元素的值最小~

code

class Solution(object):
    def smallestRange(self, llist):
        """
        :type nums: List[List[int]]
        :rtype: List[int]
        """
        ret = [0, float('inf')]
        N = len(llist)
        dp = [0 for i in range(N)]
        h, m = [], float('-inf')
        for i in range(N):
            v = llist[i][0]
            m = max(v, m)
            heapq.heappush(h, (v, i))
        while True:
            v, index= heapq.heappop(h)
            if ret[1] - ret[0] > m - v:
                ret = [v, m]
            if dp[index] == len(llist[index]) -1:
                break
            dp[index] += 1
            nv = llist[index][dp[index]]
            m = max(m, nv)
            heapq.heappush(h, (nv, index))
        return ret

总结

  • 这道题目根本不该被归类到 two pointers 类别里面, 就没有看到用 two pointers 解决的题目
原文地址:https://www.cnblogs.com/tmortred/p/13339370.html