题目描述

  输入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. 总结Idea环境,吐血踩过的坑

    1)首先是JDK环境安装,这一步千万要出错,我就是配错了CLASSPATH导致了很诡异的问题.可能结果:就是RUN到tomcat不报错,但是有404错误. 2)然后是IDEA安装,这里要十分注意如果你 ...

  2. Java 8原生API也可以开发响应式代码?

    前段时间工作上比较忙,这篇文章一直没来得及写,本文是阅读<Java8实战>的时候,了解到Java 8里已经提供了一个异步非阻塞的接口(CompletableFuture),可以实现简单的响 ...

  3. CSS3 Flex 布局教程

    网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂 ...

  4. S3 Select for Java 使用记录

    背景 后台基本使用 Amazon 的全家桶(EC2.DynamoDB.S3.Step Fuction 等等)构建.现在需要根据访问者的 IP 确定访问者的国家或地区. 已知: 访问者 IP 一个 ip ...

  5. 对博弈活动中蕴含的信息论原理的讨论,以及从熵角度看不同词素抽象方式在WEBSHELL文本检测中的效果区别

    1. 从赛马说起 0x1:赛马问题场景介绍 假设在一场赛马中有m匹马参赛,令第i匹参赛马获胜的概率为pi,如果第i匹马获胜,那么机会收益为oi比1,即在第i匹马上每投资一美元,如果赢了,会得到oi美元 ...

  6. PL/SQL 调用JAVA使用UDP发送数据

    步骤如下 1.直接在SQL命令中写入JAVA代码(用SYS帐号执行,不然权限等太麻烦) create or replace and resolve java source named udp as i ...

  7. 在github上搭建个人博客并在线更新

    换博客比更博还勤的我终于决定写一篇博客搭建教程了.. FAQ Q:\(hexo\)需要本地编译.\(jekyll\)虽然可以直接上传\(md\)..但是如果在github上直接编译也太难受了叭,毕竟不 ...

  8. Java Selenium (十二) 操作弹出窗口 & 智能等待页面加载完成 & 处理 Iframe 中的元素

    一.操作弹出窗口   原理 在代码里, 通过 Set<String> allWindowsId = driver.getWindowHandles(); 来获取到所有弹出浏览器的句柄, 然 ...

  9. node.js 初学 自我笔记整理 day01

     node.js   概念问题: Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.   npm是一个node的包管理工具  ,也是一个网站  ,还是一条命令.N ...

  10. 只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

    ## 统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生. 比较通用的返回值格式如下: ```jav ...