求数组中最小的k个数
题目:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
- package test;
- import java.util.ArrayList;
- import java.util.Comparator;
- import java.util.PriorityQueue;
- import org.junit.Test;
- public class GetLeastNumbers_Solution {
- /**
- * 基于优先队列,时间复杂度为o(nlogk)
- *
- * @param input
- * @param k
- * @return
- */
- public ArrayList<Integer> GetLeastNumbers_SolutionPriorityQuene(
- int[] input, int k) {
- ArrayList<Integer> result = new ArrayList<Integer>();
- if (input == null || input.length == 0 || k <= 0 || k > input.length)
- return result;
- PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(
- new Comparator<Integer>() {
- @Override
- public int compare(Integer o1, Integer o2) {
- return o2.compareTo(o1);
- }
- });
- for (int i = 0; i < k; i++) {
- maxHeap.offer(input[i]);
- }
- for (int j = k; j < input.length; j++) {
- if (input[j] < maxHeap.peek()) {
- maxHeap.poll();
- maxHeap.offer(input[j]);
- }
- }
- for (Integer integer : maxHeap) {
- result.add(integer);
- }
- return result;
- }
- /**
- * 基于堆排序,时间复杂度为o(nlogk)
- *
- * @param input
- * @param k
- * @return
- */
- public ArrayList<Integer> GetLeastNumbers_SolutionMaxHeap(int[] input, int k) {
- ArrayList<Integer> result = new ArrayList<Integer>();
- if (input == null || input.length == 0 || k <= 0 || k > input.length)
- return result;
- //构建最大堆
- builtMaxHeap(input,k-1);
- for (int i = k; i < input.length; i++) {
- //数组k位后的数字比堆顶小
- if (input[k] < input[0]) {
- input[0] = input[k];
- //调整堆
- builtMaxHeap(input, k - 1);
- }
- }
- for (int i = 0; i < k; i++) {
- result.add(input[i]);
- }
- return result;
- }
- /**
- * 构建、调整最大堆
- * @param a
- * @param lastIndex
- */
- public void builtMaxHeap(int[]a,int lastIndex){
- int parentIndex = ((lastIndex-1) >> 1);
- //从最后一个节点的父节点开始
- for(int i=parentIndex;i>=0;i--){
- //存在子节点
- while (i*2+1<=lastIndex){
- int leftIndex = i*2+1;
- int rightIndex = i*2+2;
- int biggerIndex = leftIndex;
- //存在右结点
- if (rightIndex <= lastIndex){
- if(a[rightIndex] > a[biggerIndex]){
- biggerIndex = rightIndex;
- }
- }
- //子节点中最大节点大于父节点
- if (a[biggerIndex] > a[i]){
- swap(a,i,biggerIndex);
- i = biggerIndex;
- }else{
- break;
- }
- }
- }
- }
- /**
- * 基于Partition函数,时间复杂度为o(n),原数组已被修改
- *
- * @param input
- * @param k
- * @return
- */
- public ArrayList<Integer> GetLeastNumbers_SolutionPartition(int[] input,
- int k) {
- ArrayList<Integer> result = new ArrayList<Integer>();
- if (input == null || input.length == 0 || k <= 0 || k > input.length)
- return result;
- int left = 0;
- int right = input.length - 1;
- int index = partition(input, 0, right);
- while (index != k - 1) {
- if (index > k - 1) {
- right = index - 1;
- index = partition(input, left, right);
- } else {
- left = index + 1;
- index = partition(input, left, right);
- }
- }
- for (int i = 0; i < k; i++) {
- result.add(input[i]);
- }
- return result;
- }
- /**
- * partition函数
- * @param a
- * @param left
- * @param right
- * @return
- */
- public int partition(int[] a, int left, int right) {
- while (left < right) {
- while (left < right && a[left] <= a[right]) {
- right--;
- }
- if (left < right) {
- swap(a, left, right);
- }
- while (left < right && a[left] <= a[right]) {
- left++;
- }
- if (left < right) {
- swap(a, left, right);
- }
- }
- return left;
- }
- public void swap(int[] a, int i, int j) {
- int tmp = a[i];
- a[i] = a[j];
- a[j] = tmp;
- }
- @Test
- public void testGetLeastNumbers_Solution() {
- int[] a = { 4, 5, 1, 6, 2, 7, 3, 8 };
- int k = 4;
- ArrayList<Integer> list = GetLeastNumbers_SolutionPartition(a, k);
- System.out.println(list.toString());
- ArrayList<Integer> list2 = GetLeastNumbers_SolutionPriorityQuene(a, k);
- System.out.println(list2.toString());
- ArrayList<Integer> list3 = GetLeastNumbers_SolutionMaxHeap(a, k);
- System.out.println(list3.toString());
- }
- }
除了基于优先队列,时间复杂度为O(nlogk)、堆排序,时间复杂度为O(nlogk)、partition函数,时间复杂度为O(n)的解法之外,还有基于冒泡排序的解法时间复杂度为(nk)。
求数组中最小的k个数的更多相关文章
- 求一个数组中最小的K个数
方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如 ...
- 【算法】数组与矩阵问题——找到无序数组中最小的k个数
/** * 找到无序数组中最小的k个数 时间复杂度O(Nlogk) * 过程: * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数 * 在堆里的k个元素中堆顶的元素是最小的k个数 ...
- [算法]找到无序数组中最小的K个数
题目: 给定一个无序的整型数组arr,找到其中最小的k个数. 方法一: 将数组排序,排序后的数组的前k个数就是最小的k个数. 时间复杂度:O(nlogn) 方法二: 时间复杂度:O(nlogk) 维护 ...
- 《程序员代码面试指南》第八章 数组和矩阵问题 找到无序数组中最小的k 个数
题目 找到无序数组中最小的k 个数 java代码 package com.lizhouwei.chapter8; /** * @Description: 找到无序数组中最小的k 个数 * @Autho ...
- 小米笔试题:无序数组中最小的k个数
题目描述 链接:https://www.nowcoder.com/questionTerminal/ec2575fb877d41c9a33d9bab2694ba47?source=relative 来 ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
- [剑指offer]数组中最小的K个数,C++实现
原创博文,转载请注明出处! http://github.com/wanglei5205 http://cnblogs.com/wanglei5205 # 题目 输入n个整数,找出其中最小的K个数.例如 ...
- 找到数组中最小的k个数
/*输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字, 则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k = ...
- 面试题四十:数组中最小的k个数
方法一:先排序后寻找前k个数: 方法二:受面试题三十九,寻找超过一半的数的启发,只把里面的middle改成k-1就行: void HalfNum( int [ ] Array ,int k){ int ...
随机推荐
- PHP 是一门弱类型语言
PHP 是一门弱类型语言 我们注意到,不必向 PHP 声明该变量的数据类型. PHP 会根据变量的值,自动把变量转换为正确的数据类型. 在强类型的编程语言中,我们必须在使用变量前先声明(定义)变量的类 ...
- 《android开发艺术探索》读书笔记(八)--WindowManager
接上篇<android开发艺术探索>读书笔记(七)--动画 No1: Window是一个抽象类,它的具体实现是PhoneWindow.创建一个Window是很简单的事,只需要通过Windo ...
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](十)
前言 朋友们, 大家好,我还是Rector,写ASP.NET MVC 5系列文章[一步一步创建ASP.NET MVC5程序Repository+Autofac+Automapper+SqlSugar] ...
- C语言老司机学Python (五)
今天看的是标准库概览. 操作系统接口: 用os模块实现. 针对文件和目录管理,还有个shutil模块可以用. 例句: import os os.getcwd() # 返回当前的工作目录 os.chdi ...
- react-dom.js 源码
/** *以下这是 react-dom.js 的源代码 * ReactDOM v15.3.1 * * Copyright 2013-present, Facebook, Inc. * All righ ...
- 【php】curl常见的错误号和解释
curl 错误代码列表 CURLE_UNSUPPORTED_PROTOCOL (1) – 您传送给 libcurl 的网址使用了此 libcurl 不支持的协议. 可能是您没有使用的编译时选项造成了这 ...
- php xml DOM编码
PHP XML文件编程 一.PHP DOM编程 <?php //1.创建dom对象 $xmldoc=new DOMDocument(); //2.加载xml(指定对哪个xml文件进行操作) $x ...
- HighCharts之2D回归直线的散点
HighCharts之2D回归直线的散点 1.实例源码 ScatterLine.html: <!DOCTYPE html> <html> <head> <me ...
- 【mongodb系统学习之九】mongodb保存数据
九.mongodb保存数据: 1).插入.保存数据:insert:语法db.collectionName.insert({"key":value}),key是字段名,必须是字符串( ...
- 错误代码: 1242 Subquery returns more than 1 row
1. 错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:SELECT t.id, DATE_FORMAT( t.statisTim ...