k-th smallest/biggest 问题大约有这几道:

373. Find K Pairs with Smallest Sums 从两个list里各取一个数求和,求所有可能的sum里第k小的
378. Kth Smallest Element in a Sorted Matrix 给一个每一横排/每一纵列都有序的matrix,求其中第k小的元素
668. Kth Smallest Number in Multiplication Table 给一个乘法表(类似378的matrix),求其中第k小的元素
719. Find K-th Smallest Pair Distance 从一个list里取两个元素求和,求所有可能的sum里第k小的
786. K-th Smallest Prime Fraction 从一个list里取两个元素相除,求所有可能的sum里第k小的

可以看出,其实373 719 786是同一题,378 668是同一题

 

这种题大致有两种思路:

1. 用heap

关于堆的介绍网上有一大把......这里只划重点

堆是一种是一种特殊的完全二叉树,其中每个根节点一定比它的左、右儿子节点都大/小(大根堆or小根堆)。每次增/删元素时,需要移动二叉树节点来保持这一性质。

时间复杂度:

从一个长度为N的乱序数组建堆  O(NlogN)

向长度为N的堆插入/删除一个元素  O(logN)

实现:

C++里可以用priority_queue<int> pq。常用操作有push(), pop(), top(), empty(), size()

Python 里可以用import heapq,然后heapq.heapify(list_a)就在原list上建好堆啦,a[0]就是堆顶。不过它只能建大根堆  

 1 import heapq
 2 
 3 #heapq implemented min heap only. Thus we save -nums[i] into the heap
 4 class Solution:
 5     def maxSlidingWindow(self, nums, k):
 6         """
 7         :type nums: List[int]
 8         :type k: int
 9         :rtype: List[int]
10         """
11         a=[]
12         res=[]
13         for i in range(len(nums)):
14             a.append(-nums[i])
15             if(i>=k):
16                 a.remove(-nums[i-k])
17             heapq.heapify(a)
18             if(i>=k-1):
19                 res.append(-a[0])
20         return res
21 
22 sl=Solution()
23 nn=[1,3,-1,-3,5,3,6,7]
24 rr=sl.maxSlidingWindow(nn,3)
25 print(rr)
Python的implementation实例(LeetCode 239的弱鸡解法)

相关文章: