题意:
给定n和k(1 <= k <= n <= 5e5),输入的n个数为1 ~ n的乱序,求前k个数,前k + 1个数,...,前n个数中第k大的数分别是多少
思路:
这题顺着想就不方便操作,因为要不断往序列里加入一些数,就算用优先队列也处理不了5e5的数据量,根据每次更新的序列做O(n)的线性时间选择也不现实,都是很繁琐且细节难实现的做法。
但是倒着处理就很顺手,我们可以先处理前n个数也就是所有数中的第k大,因为这n个数分别就是1~n,所以n个数里的第k大一定是 ans = n - k + 1。然后我们要找前n-1个数中的第k大,看下面的样例分析:
1)如果第n个数比当前的ans小,那么就算移除它也不影响当前ans在前n-1个数中的地位,也就是第k大依然是现在的ans
2)反之从长度为len的序列变到长度为len - 1的序列所要去掉的数如果比当前的ans大,那么去掉它以后在新序列里选第k大的时候,因为少了一个较大者,我们当前的ans也应该前移一位,能够前移的前提是这个数没被去掉过,因为去掉了以后他就不在新的序列中了,所以我们要给每次去掉的数打标记
3)那我们最后看一下细节问题,就是取等的情况,每次缩短序列长度要去掉的数正好等于当前ans的时候,我们也只需要直接前移一个数就可以了,与 2)同理,因为这个数已经用过被打标记了,那么就不可能让当前ans保持它
AC代码: