1. 题目:输入 n(1≤n<5000000且 n 为奇数)个数字 ,a(1≤a<10e9),输出这些数字的第 k 小的数。最小的数是第 0 小。
2.困难点:MLE
3.九大排序后再求第k小的数无法通过;利用partition方法无法通过;利用堆topk方法无法通过。
4.目前最好的情况:在n=5000000,a=random.randint(1,10e9)的条件下,堆topk和partition在时间上均可小于1s,但是内存始终不满足要求
```partition
import random import time def calc_time(func): def wrapper(ds,k): s = time.perf_counter() func(ds,k) e = time.perf_counter() print(f'running time: {e-s}') return wrapper def partition(ds, left, right): pos = random.randint(left, right - 1) ds[left], ds[pos] = ds[pos], ds[left] temp = ds[left] while left < right: while left < right and ds[right] >= temp: right -= 1 ds[left] = ds[right] while left < right and ds[left] <= temp: left += 1 ds[right] = ds[left] ds[left] = temp return left @calc_time def main(ds, k): left = 0 right = len(ds) - 1 kth = None while left < right: mid = partition(ds, left, right) if mid == k: kth = ds[mid] if mid > k: right = mid else: left = mid + 1 print(kth) # n, k = [int(i) for i in input().split()] # ds = [int(i) for i in input().split()] k = 500 ds = [random.randint(1,1000000000) for i in range(5000000)] main(ds,k)
```
```topk
import random import time def calc_time(func): def wrapper(ds,k): s = time.perf_counter() func(ds,k) e = time.perf_counter() print(f'running time: {e-s}') return wrapper def sift(ds, low, high): i = low j = 2*i + 1 temp = ds[low] while j <= high: if j+1 <= high and ds[j] < ds[j+1]: j += 1 if temp <= ds[j]: ds[i] = ds[j] i = j j = 2*i + 1 else: ds[i] = temp break else: ds[i] = temp @calc_time def topk(ds, k): for i in range(k//2, -1, -1): sift(ds, i, k) for ele in ds[k+1:]: if ele < ds[0]: ds[0] = ele sift(ds, 0, k) print(ds[0]) k = 500 ds = [random.randint(1,1000000000) for i in range(5000000)] # print(ds) topk(ds,k)
```