【算法】acwing 786 第k个数(模板题)

原题连接

给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。

输入格式
第一行包含两个整数 n 和 k。

第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整数数列。

输出格式
输出一个整数,表示数列的第 k 小数。

数据范围
1≤n≤100000,
1≤k≤n
输入样例:
5 3
2 4 1 5 3
输出样例:
3

这是快排变题,先看一手快排的模板

import java.util.*;

public class Main{
    public static void main (String args[]){
        Scanner sc =  new Scanner(System.in);
        int n = sc.nextInt();
        int [] a = new int [n];
        for(int i = 0; i < n; i++)a[i] = sc.nextInt();

        quickSort(a,0,n-1);

        for(int i = 0; i < n;i++ )System.out.print(a[i] + " ");
    }

    public static void quickSort(int [] a,int l, int r){
        if(l >= r) return;
        int i = l - 1, j = r + 1, x = a [l+r>> 1];
        while(i < j){
            do i ++;while(a[i] < x);
            do j --;while(a[j] > x);

            if( i < j){
                int t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }
        quickSort(a,l,j);
        quickSort(a,j+1,r);
    }
}

这题在递归的时候不需要递归两边处理

  • 当左边sl <= k 时 递归左边即可
  • 当 sl > k 时,递归右边即可,但此时的k = k - sl

ac code

import java.util.*;

public class Main{
    static int[] a;
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        a = new int[n];
        for(int i = 0; i < n; i++)a[i] = sc.nextInt();
        System.out.println(quickSort(0, n - 1, k));
    }

    public static int quickSort(int l,int r,int k){
        if(l == r)return a[l];
        int x = a[l + r >> 1],i = l - 1,j = r + 1;
        while(i < j){
            while(a[++ i] < x);
            while(a[-- j] > x);
            if(i < j){
                int t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }
        int sl = j - l + 1;
        if(k <= sl)return quickSort(l,j,k);

        return quickSort(j + 1,r, k - sl);
    }
}

空间复杂度o(n),
时间复杂度 n + n/2 + n/4 + n / 8 ... ≈2n ,∴o(n)。

全部评论

相关推荐

饥饿的长颈鹿就要上岸...:简历五项结构 简历只放五项内容,顺序和格式如下: 一、个人信息 只写名字、电话、邮箱 不写性别、年龄、籍贯、政治面貌、微信等额外信息 二、教育经历 格式:学校名称 | 学历 | 专业 | 就读时间 从左到右排列,一行写完 如果专业和岗位对口,写1-2行主修课程;不对口就不写 学历如果不占优势,可以把教育经历放到简历靠后的位置 三、实习/项目经历 如果没有实习经历,全部写项目经历 每条经历格式:项目名 + 岗位名 + 任职时间段 下面写三到五条工作内容 每条工作内容开头必须用四个字概括,加粗,后面跟一条完整描述 所有描述必须用STAR法则来写(情境-任务-行动-结果) 每一条都要有数据支撑和具体成果 四、个人优势 可以写获得的奖项、证书 如果奖项不够,就写你熟练掌握的技能 每条也要有具体数据或成果支撑,不能空泛堆砌 五、整体要求 一页纸,不要超过一页 个人信息只写名字加电话邮箱 贝贝试一下这个方式写简历,我虽然没收到offer,至少收到了好几轮面试
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务