题目描述

  输入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. vue通信、传值的多种方式(详细)

    转载自https://blog.csdn.net/qq_35430000/article/details/79291287

  2. C#:正则表达式类

     Regex r = new Regex("abc"); // 定义一个Regex对象实例(Regex r = new Regex("abc", RegexOp ...

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

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

  4. java 学习路线、java 入门、java自学、java 教程

    以前学习知识都是用到什么学什么,不是很系统.今天看到一个网站感觉挺不错的,分享给大家. 这个页面是学习路线功能的简介,如下图 ​ 点击选择学习路线 ​ 进入后可以选择循序渐进或者由终至始 ​ 上图标出 ...

  5. CSS3:pointer-events | a标签禁用

    用纯css就能实现取消事件响应的方法,pointer-events,使用起来更加简单,它可以: pointer-events: auto | none | visiblePainted | visib ...

  6. Tunnel Warfare HDU - 1540 (线段树不同子树的合并)

    在抗日战争期间,华北平原广大地区进行了大规模的隧道战. 一般来说,通过隧道连接的村庄排成一列. 除了两端,每个村庄都与两个相邻的村庄直接相连. 入侵者经常对一些村庄发动袭击并摧毁其中的部分隧道. 八路 ...

  7. 网络安全攻击与防护--HTML学习

    第一节. HTML基本语法(文末有对该文视频讲解) HTML的官方介绍什么的我就不说了,打字也挺累的,只简单介绍一下吧,其他的懂不懂都没关系. HTML全称为Hypertext Markup Lang ...

  8. 实现API管理系统的几个重要关键词

    管理API的需求源自于Web API开展业务.从2006年开始,然后逐渐成熟,并在2016年之前进入市场.无论是通过代理现有API的管理网关.本身作为用于部署API本身的网关的一部分,还是作为连接层在 ...

  9. 导入spark2.3.3源码至intellij idea

    检查环境配置 maven环境 2.检查scala插件 没有的话可以到https://plugins.jetbrains.com/plugin/1347-scala/versions 下载与idea对应 ...

  10. 神经网络 OCR 参考

    1. https://blog.csdn.net/u010159842/article/details/87271554 2. https://blog.csdn.net/weixin_4286104 ...