题目描述

  输入n个整数,找出其中最小的k个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

牛客网刷题地址

思路分析

  1. 利用Patition函数,将数组分成两部分,判断返回的值是否在第k个位置,如果是,那么前k个数即为所求的数,如果小于k,那么在右边,如果大于k,在左边。
  2. 利用大顶推,将数组中前k个值放入大顶推中,后面的继续放入大顶推,如果后面的数值小于大顶推中最大数,就与之交换,如果大于最大值,就继续往后遍历。

测试用例

  1. 功能测试:输入的数组中有相同的数字;输入的数组中没有相同的数字。
  2. 边界值测试:输入的k等于1或者等于数组的长度。
  3. 特殊输入测试:k小于1;k大于数组的长度;指向数组的指针为NULL。

Java代码

public class Offer040 {
public static void main(String[] args) {
test1();
test2();
test3(); } public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
return Soltuion2(input, k);
} /**
* partition的思路: 利用Partition 第k个位置的分界线,左边的值比第k个位置的值小,右边的比它大, 那么,左边的k个数就是所要求的值
*
* @param input
* @param k
* @return
*/
private static ArrayList<Integer> Soltuion1(int[] input, int k) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (input == null || input.length < 0 || k <= 0 || k > input.length) {
// 这里要判断k的取值
return list;
}
int low = 0;
int high = input.length - 1;
int index = Partition(input, low, high); while (index != k - 1) {
if (index < k - 1) {
low = index + 1;
index = Partition(input, low, high);
} else {
high = index - 1;
index = Partition(input, low, high);
}
}
for (int i = 0; i < k; i++) {
list.add(input[i]);
}
return list;
} private static int Partition(int[] input, int low, int high) {
int pivot = input[low];
while (low < high) {
while (low < high && input[high] >= pivot)
high--;
input[low] = input[high];
while (low < high && input[low] <= pivot)
low++;
input[high] = input[low];
}
input[low] = pivot;
return low;
} /**
* 思路二:
*
* @param input
* @param k
* @return
*/
private static ArrayList<Integer> Soltuion2(int[] input, int k) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (input == null || input.length < 0 || k <= 0 || k > input.length) {
// 这里要判断k的取值
return list;
}
int[] numbers = new int[k];
for(int i=0;i<k;i++) {
numbers[i]=input[i]; //放入前k个数
}
for(int i=k/2-1;i>=0;i--) {
adjustDown(numbers,i); //向下调整大顶堆
} for(int i =k;i<input.length;i++) {
if(input[i]<numbers[0]) {
numbers[0] = input[i];
adjustDown(numbers, 0);
} } for (int num : numbers) {
list.add(num);
}
return list;
} private static void adjustDown(int[] numbers, int k) {
int tmp = numbers[k];//保存要调整的值
for(int i=k*2+1;i<=numbers.length-1;i=i*2+1) {//因为k要遍历到索引0,索引需要+1 if(i<numbers.length-1 && numbers[i]<numbers[i+1]) {
i++; //将i的索引指向左右子节点中最大的值
}
if(tmp>=numbers[i]) break; // 如果要调整的值大于它左右子节点中最大的数,就不需要调整了
else {
numbers[k] = numbers[i];//与最大的值交换
k=i;//修改k值,继续向下调整
}
}//for
numbers[k] = tmp; //被筛选的值放入最终位置
} private static void test1() {
int[] input = { 4, 5, 1, 6, 2, 7, 3, 8 };
ArrayList<Integer> list = GetLeastNumbers_Solution(input, 4);
System.out.println(list);
} private static void test2() { } private static void test3() { }
}

代码链接

剑指Offer代码-Java

【Offer】[40] 【最小的K个数】的更多相关文章

  1. 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序

    剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...

  2. 剑指 Offer 40. 最小的k个数

    剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:ar ...

  3. 【Java】 剑指offer(40) 最小的k个数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...

  4. 每日一题 - 剑指 Offer 40. 最小的k个数

    题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 快排 难易程度:中等 题目描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3. ...

  5. 【剑指Offer】最小的K个数 解题报告(Python)

    [剑指Offer]最小的K个数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目 ...

  6. 剑指offer 面试题40. 最小的k个数

    O(N)划分法,注意这个方法会改变原数据(函数参数是引用的情况下)!当然也可以再定义一个新容器对其划分 要求前k小的数,只要执行快排划分,每次划分都会把数据分成大小两拨.直到某一次划分的中心点正好在k ...

  7. 《剑指offer》面试题40. 最小的k个数

    问题描述 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k ...

  8. Go语言实现:【剑指offer】最小的K个数

    该题目来源于牛客网<剑指offer>专题. 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. Go语言实现: fu ...

  9. 剑指OFFER之最小的K个数(九度OJ1371)

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1< ...

  10. 剑指Offer 29. 最小的K个数 (其他)

    题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 题目地址 https://www.nowcoder.com/prac ...

随机推荐

  1. 昏睡了8年的我带着第一个微信小程序今年醒了

    工作8年之久的我今年算是彻底长进了,以前是知道自己的水平不咋地,但是没什么行动,理由是3年抱2娃,需要照顾孩子. 去年年底偶然一次看技术贴的时候,看到了博客园这个平台,看了很多大牛们的经历,也知道公司 ...

  2. GridView 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  3. 【Java例题】8.1手工编写加法器的可视化程序

    1. 手工编写加法器的可视化程序. 一个Frame窗体容器,布局为null,三个TextField组件,一个Button组件. Button组件上添加ActionEvent事件监听器ActionLis ...

  4. Spring Boot 整合 JPA 使用多个数据源

    介绍 JPA(Java Persistence API)Java 持久化 API,是 Java 持久化的标准规范,Hibernate 是持久化规范的技术实现,而 Spring Data JPA 是在 ...

  5. PIP键盘设置实时时钟--智能模块

    大家好,许久没来发帖,今天带来点干货.希望大家多多讨论,相互学习. 使用 TOPWAY Smart LCD (HMT050CC-C) PIP键盘设置实时时钟   第一步  建立工程  第二步  建立2 ...

  6. 为什么unsigned (-1)表示无符号整数的最大值

    整数在计算机中的表示 在计算机中,整数采用补码表示.当前主流编译器中整型在内存中占用四个字节,共32位. 机器数:一个数在计算机中的二进制表示形式, 叫做这个数的机器数.机器数是带符号的,在计算机用一 ...

  7. 对Java中HashCode方法的深入思考

    前言 最近在学习 Go 语言,Go 语言中有指针对象,一个指针变量指向了一个值的内存地址.学习过 C 语言的猿友应该都知道指针的概念.Go 语言语法与 C 相近,可以说是类 C 的编程语言,所以 Go ...

  8. ABAP 查看采购订单行项目已开票金额和已清金额

    FUNCTION zmm_fm_po_invence. *"----------------------------------------------------------------- ...

  9. 自己实现spring核心功能 二

    前言 上一篇我们讲了spring的一些特点并且分析了需要实现哪些功能,已经把准备工作都做完了,这一篇我们开始实现具体功能. 容器加载过程 我们知道,在spring中refesh()方法做了很多初始化的 ...

  10. Ubuntu下安装php7.1的gd,mysql,pdo_mysql扩展库

    执行以下命令 # apt-get install php7.1-gd # apt-get install php7.0-mysql 重新启动 php7.1-fpm(因为我是安装的 Nginx 和 ph ...