剑指:最小的k个数
题目描述
输入 n 个整数,找出其中最小的 K 个数。例如输入 4,5,1,6,2,7,3,8 这 8 个数字,则最小的 4 个数字是 1,2,3,4。
解法
解法一
利用快排中的 partition 思想。
数组中有一个数字出现次数超过了数组长度的一半,那么排序后,数组中间的数字一定就是我们要找的数字。我们随机选一个数字,利用 partition() 函数,使得比选中数字小的数字都排在它左边,比选中数字大的数字都排在它的右边。
判断选中数字的下标 index:
- 如果
index = k-1,结束循环,返回前 k 个数。 - 如果
index > k-1,那么接着在 index 的左边进行 partition。 - 如果
index < k-1,则在 index 的右边继续进行 partition。
注意,这种方法会修改输入的数组。时间复杂度为 O(n)。
public class Solution {
public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k){
ArrayList<Integer> res = new ArrayList<>();
if(input==null || input.length==0||input.length<k||k<1){
return null;
}
int n= input.length;
int start=0;
int end = n-1;
int p = partition(input, start, end);
while(p != k-1){
if(p>k-1){
end = p-1;
}else{
start = p+1;
}
p = partition(input, start, end);
}
for(int i=0; i<k; i++){
res.add(input[i]);
}
return res;
}
private static int partition(int[] arr, int start, int end) {
int p = arr[start];
while(start<end){
while(start<end && arr[end]>=p) end--;
arr[start] = arr[end];
while(start<end && arr[start]<=p) start++;
arr[end] = arr[start];
}
arr[start] = p;
return start;
}
public static void main(String[] args) {
int[] arr = {1,2,9,3,0,8,7,5,6,4};
int k = 5;
ArrayList nums = GetLeastNumbers_Solution(arr, k);
for(int i=0;i<nums.size();i++){
System.out.println(nums.get(i));
}
}
}
解法二
利用大根堆,存储最小的 k 个数,最后返回即可。
此方法时间复杂度为 O(nlogk)。虽然慢一点,但是它不会改变输入的数组,并且它适合海量数据的输入。
假设题目要求从海量的数据中找出最小的 k 个数,由于内存的大小是有限的,有可能不能把这些海量的数据一次性全部载入内存。这个时候,用这种方法是最合适的。就是说它适合 n 很大并且 k 较小的问题。
public class Solution {
public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k){
ArrayList<Integer> res = new ArrayList<>();
if(input==null || input.length==0||input.length<k||k<1){
return null;
}
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, Comparator.reverseOrder());
System.out.println("maxHeap_size:" + maxHeap.size());
for (int e : input) {
if (maxHeap.size() < k) {
maxHeap.add(e);
} else {
if (maxHeap.peek() > e) {
maxHeap.poll();
maxHeap.add(e);
}
}
}
res.addAll(maxHeap);
return res;
}
public static void main(String[] args) {
int[] arr = {1,2,9,3,0,8,7,5,6,4};
int k = 4;
ArrayList nums = GetLeastNumbers_Solution(arr, k);
for(int i=0;i<nums.size();i++){
System.out.println(nums.get(i));
}
}
}
剑指:最小的k个数的更多相关文章
- 【Java】 剑指offer(40) 最小的k个数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...
- 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)
注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...
- 剑指Offer - 九度1371 - 最小的K个数
剑指Offer - 九度1371 - 最小的K个数2013-11-23 15:45 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是 ...
- 【剑指Offer面试题】 九度OJ1371:最小的K个数
题目链接地址: http://ac.jobdu.com/problem.php?pid=1371 题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265 ...
- 剑指Offer(二十九):最小的K个数
剑指Offer(二十九):最小的K个数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...
- Go语言实现:【剑指offer】最小的K个数
该题目来源于牛客网<剑指offer>专题. 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. Go语言实现: fu ...
- 【剑指Offer面试编程题】题目1371:最小的K个数--九度OJ
题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1< ...
- 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序
剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...
- 剑指 Offer 40. 最小的k个数
剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:ar ...
- 最小的K个数 牛客网 剑指Offer
最小的K个数 牛客网 剑指Offer 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. class Solution ...
随机推荐
- Java8——jdk——java.time包
public class TestLocalDateTime { //6.ZonedDate.ZonedTime.ZonedDateTime : 带时区的时间或日期 @Test public void ...
- Eclipse分享和检出(六)
一.创建资源库位置 1. 切换到透视图 SVN 资源库:Window--Show View--Other,搜索“SVN资源库” 2. 创建资源库位置,右键--新建--资源库位置 3. 输入可用的版 ...
- 关于matlab tfdata的用法
加上'v',可以让输出的值由元胞数组改为数组直接输出:举个例子:h = tf([1 1],[1 2 5]);[num,den] = tfdata(h)可以看出输出的num和den为元胞数组的形式无 ...
- <Tree.PreOrder> DFS 113, 129
113. Path Sum II 利用DFS的三要素, 出口1,出口2,拆解,记得回溯的时候要回退一位path. class Solution { public List<List<Int ...
- [LeetCode] 20. Valid Parentheses 验证括号
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...
- LeetCode 220. Contains Duplicate III (分桶法)
Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...
- Visual Studio 调试系列3 断点
系列目录 [已更新最新开发文章,点击查看详细] 断点是开发人员的工具箱中最重要的调试技术之一. 若要暂停调试程序执行所需的位置设置断点. 例如,你可能想要查看代码变量的状态或查看调用堆栈的某些 ...
- prometheus consul docker redis_exporter 自动注册配置
0.启动redis_exporter redis_exporter: version: '2'services: redis_exporter: image: oliver006/redis_expo ...
- Servlet的Listener介绍
当Web应用在Web容器中运行时,Web应用内部会不断地发生各种事件:如Web应用被启动.Web应用被停止.用户session开始.用户session结束等.通常这些Web操作对开发者是透明的.但Se ...
- .NET Core:路由
(1)模板路由 在Startup的Configure方法中配置: app.UseMvc(routes =>{ routes.MapRoute( name: "areas", ...