剑指 Offer 40. 最小的k个数

Offer_40

题目描述

解法一:排序后取前k个数

/**
* 题目描述:输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
*/
/**
* 方法一:先对数字进行排序,然后依次找到最小的k个数
*/
public class Offer_40 {
public int[] getLeastNumbers(int[] arr, int k) {
if(arr == null || arr.length == 0 || k==0)
return new int[0];
Arrays.sort(arr);
int[] result = new int[k];
int index = 1;
result[0] = arr[0];
for(int i = 1; i<arr.length; i++){
if(index >= k)
break;
if(arr[i] != arr[i-1]){
result[index++] = arr[i];
}
}
return result;
}
}

解法二:使用大根堆维护k个最小的数

/**

 * 方法二:使用大根堆维护k个最小的数
*/
class Offer_40_1 {
public int[] getLeastNumbers(int[] arr, int k) {
if(arr == null || arr.length == 0 || k==0)
return new int[0];
int[] result = new int[k];
//java的优先队列默认是小根堆实现,而c++中默认是大根堆实现。
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
//自定义排序器,降序排序
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for(int i = 0;i<k; i++){
priorityQueue.offer(arr[i]);
}
for(int i=k; i<arr.length; i++){
if(priorityQueue.peek() > arr[i]){
priorityQueue.poll();
priorityQueue.offer(arr[i]);
}
}
for(int i=0;i<k;i++){
result[i] = priorityQueue.poll();
}
return result;
}
}

解法三:使用快速排序的思想找前k个最小的数

/**
* 方法三:使用快排的思想
*/
class Offer_40_2 {
/**
* 一趟排序,每一趟返回一个数的确定位置
* @param arr
* @param l
* @param r
* @return
*/
int partition(int[] arr, int l, int r){
int fix = arr[l];//需要确定arr[l]的位置
while(l<r){
while(arr[r] >= fix && l<r)
r--;
if(l<r){
arr[l] = arr[r];
l++;
}
while(arr[l] <= fix && l<r)
l++;
if(l<r){
arr[r] = arr[l];
r--;
}
}
//最后才确定fix的位置
arr[l] = fix;
return l;
} /**
* 查找最小的k个数
* @param arr
* @param k
* @param l
* @param r
*/
int[] quickSort(int[] arr, int k, int l, int r){
int index = partition(arr, l, r);
if(index == k-1){
int[] result = new int[k];
result = Arrays.copyOf(arr, k);
return result;
}else if(index <k-1){//找到的index个数小于k个,需要继续往右半部分递归查找
return quickSort(arr, k, index+1, r);
}else{
return quickSort(arr, k, l, index-1);
}
} public int[] getLeastNumbers(int[] arr, int k) {
if(arr == null || arr.length == 0 || k==0)
return new int[0];
return quickSort(arr, k, 0, arr.length -1);
}
}

剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 《剑指offer》最小的k个数

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

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

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

  9. 【剑指offer】最小的K个数

    一.题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.思路: 一群大牛在讨论用噼里啪啦各种排序,复杂度一般也都是O ...

随机推荐

  1. 关于最小生成树 Kruskal 和 Prim 的简述(图论)

    模版题为[poj 1287]Networking. 题意我就不说了,我就想简单讲一下Kruskal和Prim算法.卡Kruskal的题似乎几乎为0.(●-`o´-)ノ 假设有一个N个点的连通图,有M条 ...

  2. Ubuntu——常用命令

    一.进入文件夹 1.cd .. # 进入上一个文件夹 2.cd ../.. # 进入上两个文件夹 3.cd - # 去到进入当前文件夹之前的那个文件夹 二.复制文件 cp 目标文件 复制文件名 三.移 ...

  3. Win10永久禁用驱动程序强制签名

    在win10下用一个命令就可以禁用驱动程序强制签名 1.禁止强制签名,以管理员的身份运行cmd 执行以下命令 bcdedit.exe /set nointegritychecks on 恢复默认验证, ...

  4. POJ - 3665 icow

    Fatigued by the endless toils of farming, Farmer John has decided to try his hand in the MP3 player ...

  5. 容器之List接口下各实现类(Vector,ArrayList 和LinkedList)的线程安全问题

    Vector .ArrayList 和LinkedList都是List接口下的实现类,但是他们之间的区别和联系是什么呢? 首先: 然后: 如果您仅仅想知道结论,那么可以关闭了. 下面我讨论讨论为什么. ...

  6. vue-router离开当前页面提示未保存,解决在使用beforeRouteLeave弹窗多次闪现问题

    在使用beforeRouteLeave时要注意两点: 1. next(false)阻止路由继续进行,若不先阻止,会多次执行守卫中的代码 2. 利用setTimeout延时触发弹窗,避免出现闪现情况

  7. Hive Tutorial 阅读记录

    Hive Tutorial 目录 Hive Tutorial 1.Concepts 1.1.What Is Hive 1.2.What Hive Is NOT 1.3.Getting Started ...

  8. adjust All In One

    adjust All In One 调整 https://www.adjust.com/ Maximize the impact of your mobile marketing Adjust is ...

  9. React 性能优化 All In One

    React 性能优化 All In One Use CSS Variables instead of React Context https://epicreact.dev/css-variables ...

  10. Self-XSS All In One

    Self-XSS All In One Self-XSS(自跨站脚本)攻击 警告! 使用此控制台可能会给攻击者可乘之机,让其利用 Self-XSS(自跨站脚本)攻击来冒充您并窃取您的信息.请勿输入或粘 ...