美文网首页
2020-2-18 刷题总结「第 k 小问题」

2020-2-18 刷题总结「第 k 小问题」

作者: madao756 | 来源:发表于2020-02-18 18:23 被阅读0次

    0X00 leetcode 刷题

    • LeetCode 378. Kth Smallest Element in a Sorted Matrix
    • LeetCode 668. Kth Smallest Number in Multiplication Table
    • LeetCode 786. K-th Smallest Prime Fraction
    • LeetCode 719. Find K-th Smallest Pair Distance

    0X01 基本模板总结

    首先我们有这么一个基本问题

    给定一个升序的数组:
    
    [1, 5, 9, 10, 10, 20]
    
    给定最小值 1 最大值 20 求 第 k 小的元素
    

    hebing

    对于第 kth 小的问题,有一种通用解法就是用 k size 的「最大堆」,这个以后再说,今天我们主要用二分查找

    二分查找有一个模板:

    lo, hi = min, max
    while lo < hi:
        mid = lo + (hi - lo) // 2
        if check(xx):
            r = m
        else:
            l = m + 1
     return l
    

    对于这个问题我们的解法如下:

    class Solution:
        def kth(self, nums, minNumber, maxNumber, k):
            l, r = minNumber, maxNumber
    
            # 返回比 n 小于等于的个数
            def helper(start, end, nums, n):
                if start == end:
                    return 1 if n > nums[start] else 0
                if end - start == 1:
                    if n >= nums[end]: return 2
                    if n >= nums[start]: return 1
                    return 0
                if n > nums[end]:
                    return end - start + 1
                mid = start + (end - start) // 2
                
                return helper(start, mid, nums, n) + helper(mid+1, end, nums, n)
    
                return start
    
            while l < r:
                m = l + (r - l) // 2
                if helper(m) >= k:
                    r = m
                else:
                    l = m + 1
    
            return l
    
    
    a = [1, 4, 5, 5, 5, 5, 5, 5, 8]
    s = Solution()
    print(s.kth(a, 1, 8, 4))
    

    对于这一种解法,一直有一个这么样的疑问

    为什么二分搜索出来的值,一定在数组里面..

    1. 一定存在第 k 小的值,而且是唯一的
    2. 一定是 r 先找到最后的答案
    3. r 找到答案后就不会改变了, 直到 l 与 r 合并

    0X02 leetcode 做题

    378. Kth Smallest Element in a Sorted Matrix

    不是最优解..但是就是按照上面的模板改的...

    如果有重复元素的话,我就还是用递归吧.迭代太复杂了

    class Solution:
        def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
            lo, hi = matrix[0][0], matrix[-1][-1]
    
            def helper(start, end, nums, n):
                if start == end:
                    return 1 if n >= nums[start] else 0
                if end - start == 1:
                    if n >= nums[end]: return 2
                    if n >= nums[start]: return 1
                    return 0
                if n >= nums[end]:
                    return end - start + 1
                mid = start + (end - start) // 2
                return helper(start, mid, nums, n) + helper(mid+1, end, nums, n)
    
    
            while lo < hi:
                mid = lo + (hi - lo) // 2
                s = 0
                for row in matrix:
                    s += helper(0, len(row) - 1, row, mid)
                if s  >= k:
                    hi = mid
                else:
                    lo = mid + 1
            
            return lo
    

    668. Kth Smallest Number in Multiplication Table

    class Solution:
        def findKthNumber(self, m: int, n: int, k: int) -> int: 
            
            # 返回有多少个 <= x 的数
            def helper(m, n, k, x):
                count = 0
                # 只需要把每一行的 x // i 加起来就行了
                # 如果 i 大于 x  x // i == 0 也就不需要继续算下去了
                # 如果 m < x 那么剩下的也不用算了
                # 所以最大值是 min(x, m)
                for i in range(1, min(m+1, x+1)):
                    # 一行长度可能不够
                    count += min(x // i, n)
                    # 剪枝
                    if count >= k: return count
                return count
            
            l, r = 1, m * n + 1
    
            while l < r:
                mid = l + (r - l) // 2
                if helper(m,n, k, mid) >= k:
                    r = mid
                else:
                    l = mid + 1
    
            return l
    

    这道题用了模板题的结论,

    在有重复的升序列数组中找到

    下面两道题待做

    786. K-th Smallest Prime Fraction

    719. Find K-th Smallest Pair Distance

    相关文章

      网友评论

          本文标题:2020-2-18 刷题总结「第 k 小问题」

          本文链接:https://www.haomeiwen.com/subject/wthnfhtx.html