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)