首页 > 其他分享 >第k小的数

第k小的数

时间:2024-12-11 11:32:53浏览次数:5  
标签: 右边 int ll mid while lr

原题在这里
题目大意:给定n个数,求出这n个数中第k小的数。

做法:

  1. 首先直接想到的肯定是直接排序然后O(1)输出即可。这样的时间复杂度是O(nlogn),由于题目中n的数据范围过大我们无法接受。
  2. 再想到,我们在进行快速排序的过程中,随机选取一个数作为基准,每次将比它大的数放到它的左边,比它小的数放到它的右边,那么我们是不是可以考虑:当任选取一个基准并进行以上操作之后,如果我们要求的第k小的数在这个基准的左边,那我们只需要递归左边就可以了,右边的数对得出答案是没有贡献的。反之如果在右边,那么只需要递归右边即可。这样就避免了大量的无效操作,时间复杂度也来到了O(n)。
void quicksort(int l,int r) {
    int mid = a[(l + r) >> 1];
    int ll = l,lr = r;
    do {
        while(a[ll] < mid) ll++;
        while(a[lr] > mid) lr--;
        if(ll <= lr) {
            swap(a[ll],a[lr]);
            ll++;
            lr--;
        }
    }while(ll <= lr);
    if(k >= ll) quicksort(ll,r);
    else if(k <= lr) quicksort(l,lr);
    else {
        cout << a[k];
        return;
    }
}

注意我们在进行一次do-while操作之后ll应该是大于lr的,也就是整个区间被分为了ll <= lr < ll <= r这三部分,也就导致了后面的if语句中为什么是k >= ll, k <= lr和ll < k < lr这三种情况。
3. STL当中给我们提供了一个非常方便的函数nth_element(a+x,a+x+y,a+x+n),作用是使a数组中下标x到x+y-1的元素都小于a[x+y],而x+y+1到x+n的元素都大于a[x+y],这样此题就会变得非常简单。

标签:,右边,int,ll,mid,while,lr
From: https://www.cnblogs.com/lwiwi/p/18599109

相关文章