题解 | #输入n个整数,输出其中最小的k个#

输入n个整数,输出其中最小的k个

https://www.nowcoder.com/practice/69ef2267aafd4d52b250a272fd27052c

题解思路:输出最小的k个数,我首先想到的是先排序再遍历输出。但排序用哪种方式好呢?感觉冒泡、插入、选择都可以,只需要排出前k个即可,快排和归并感觉不是很有必要,因为这样会将所有数据进行排序,有些多此一举。当然对于Top k 类型的算法,堆排序肯定是最佳的选择。Java中PriorityQueue是通过完全二叉树实现的小顶堆,使用起来很方便,省去了自己构建堆的麻烦。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Scanner scanner = new Scanner(br);
        int num = scanner.nextInt();
        int k = scanner.nextInt();
        int[] nums = new int[num];
        for (int i = 0; i < num; i++) {
            nums[i] = scanner.nextInt();
        }
        String result = getSmallestNumberOfK_2(nums,k);
        System.out.println(result);
    }
    // 投机取巧的解法
    private static String getSmallestNumberOfK_3(int[] nums, int k) {
        if (k <= 0 || nums == null || nums.length == 0) return null;
        StringBuilder builder = new StringBuilder();
        Arrays.sort(nums);
        for (int i = 0; i < k; i++) {
            builder.append(nums[i]).append(" ");
        }
        return builder.toString().trim();
    }
    // 使用堆排序解决
    private static String getSmallestNumberOfK_2(int[] nums, int k) {
        if (k <= 0 || nums == null || nums.length == 0) return null;
        StringBuilder builder = new StringBuilder();
        PriorityQueue<Integer> heap = new PriorityQueue<>();
        for (int i = 0; i < nums.length; i++) {
            heap.add(nums[i]);
        }
        for (int i = 0; i < k; i++) {
            builder.append(heap.poll()).append(" ");
        }
        return builder.toString().trim();
    }
    // 使用选择排序解决
    private static String getSmallestNumberOfK_1(int[] nums,int k) {
        if (k <= 0 || nums == null || nums.length == 0) return null;
        StringBuilder builder = new StringBuilder();
        selectort(nums,k);
        for (int i = 0; i < k; i++) {
            builder.append(nums[i]).append(" ");
        }
        return builder.toString().trim();

    }

    private static void selectort(int[] nums,int k) {
        int min;
        for (int i = 0; i < nums.length-1; i++) {
            min = i;
            for (int j = i+1; j < nums.length; j++) {
                if (nums[j] < nums[min]){
                    min = j;
                }
                if (i == k) break;
            }
            if (min != i)
                swap(nums,i,min);
        }
    }
    private static void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }

}


#笔试刷题#
全部评论

相关推荐

已oc&nbsp;云智断更了好几天,也有一些话想说,继续更新一篇云智timeline&nbsp;4.18&nbsp;一面&nbsp;半个小时后约二面&nbsp;4.21二面&nbsp;当晚&nbsp;约hr面&nbsp;4.23hr面&nbsp;4.30&nbsp;发offer之前美团的二面挂了,进入人才库,后面又被捞起来面试,4.30号&nbsp;美团又一面,现在还没出一面结果感觉也不报什么希望,就算一面过了,还有二面,我经不起深入拷打,唉,真的,好难五一躺平了五天,吃吃玩玩睡睡~还要担心毕业,科研更是难,唉暑期可能就到此为止了,后面没有时间在这个上面了,要抓紧时间做科研,为了后面能出去实习。大厂,秋招再见!!!有一些感慨:4.1是我的第一次面试,美团,面试的时候紧张到浑身发...
daisy9542:我今晚也是美团一面,已经第六次了。我也面了其他的,没拿到 offer。但我想开了,要按照自己的节奏来,找暑期转正然后秋招大杀四方并不是唯一的出路,其实还有很多选择的,有 0 实习最后秋招拿 offer 了,也有不选择互联网去国企的外企的,考编的,创业的。现在的失败不代表以后的路都是黑暗的,只不过可能运气还没降临到头上。所以现在要做的,就是放平心态,提升自己,通过面试了解到自己的优点和不足,争取下次机会来了能好好抓住
点赞 评论 收藏
分享
评论
14
2
分享

创作者周榜

更多
牛客网
牛客企业服务