题目描述

  输入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. c++随笔之编译器编译原理

    /* C++编译器原理:1)首先明白声明与定义是两个不同的概念 extern int i;是声明,int i;是定义 函数就更简单了2)编译分为: 预编译:将宏替换,include等代码拷贝过来 编译 ...

  2. 《机器学习基石》---Linear Models for Classification

    1 用回归来做分类 到目前为止,我们学习了线性分类,线性回归,逻辑回归这三种模型.以下是它们的pointwise损失函数对比(为了更容易对比,都把它们写作s和y的函数,s是wTx,表示线性打分的分数) ...

  3. 解放双手——相机与IMU外参的在线标定

    本文作者 沈玥伶,公众号:计算机视觉life,编辑部成员 一.相机与IMU的融合 在SLAM的众多传感器解决方案中,相机与IMU的融合被认为具有很大的潜力实现低成本且高精度的定位与建图.这是因为这两个 ...

  4. npm钉钉脚手架,支持考勤信息获取

    钉钉官方并未提供nodejs包,第一次调用接口的时候非常费事,而且尝试去寻找相关的钉钉考勤数据模块的时候只找到了一些消息啊,只能办公啊,免登啊之类的模块,有关考勤数据的似乎没有 关于dd的npm包中一 ...

  5. (四十五)c#Winform自定义控件-水波图表

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  6. linux 下 VSCODE 使用CMake编译STM32程序

    项目在做什么 项目地址 本项目是为了研究MCU在linux下开发而做的 --build 存放cmake编译生成的文件 --cmake 存放cmake编译时会用到的文件,比如工具链检查.编译选项等 -- ...

  7. MySQL MGR集群单主模式的自动搭建和自动化故障修复

    随着MySQL MGR的版本的升级以及技术成熟,在把MHA拉下神坛之后, MGR越来越成为MySQL高可用的首选方案.MGR的搭建并不算很复杂,但是有一系列手工操作步骤,为了简便MGR的搭建和故障诊断 ...

  8. Pyinstaller打包多个.py文件

    https://blog.csdn.net/CholenMine/article/details/80964272

  9. (springboot)自定义Starter

    要引入的jar项目,即自定义的Starter项目: pom:(这里不能引入springboot整合否则测试项目注入失败) <?xml version="1.0" encodi ...

  10. Visual Studio 2019 远程调试工具(Remote Debugger)使用方法

    目录 0.Visual Studio 2019 远程调试工具使用场景 1.Visual Studio 2019 远程调试工具下载地址: 2.Visual Studio 2019 远程调试工具-安装及运 ...