【算法】数组与矩阵问题——找到无序数组中最小的k个数

 1 /**
 2  * 找到无序数组中最小的k个数 时间复杂度O(Nlogk)
 3  * 过程:
 4  * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数
 5  *     在堆里的k个元素中堆顶的元素是最小的k个数中最大的那个。
 6  * 2.接下来,遍历整个数组,遍历过程中看当前数是否比堆顶元素小:
 7  *     如果是,就把堆顶元素替换成当前的数,然后从堆顶的位置调整整个堆,让替
 8  *     换操作后堆的最大元素继续处在堆顶的位置;
 9  *     如果不是,则不进行任何操作,继续遍历下一个数;
10  * 3.在遍历完成后,堆中的k个数就是所有数组中最小的k个数
11  */
12 public class getMinKNumsByHeap {
13
14     public int[] getMinKNumsByHeap(int[] arr, int k) {
15         if (k < 1 || k > arr.length) {
16             return arr;
17         }
18         int[] kHeap = new int[k];
19         for (int i = 0; i < k; i++) {
20             heapInsert(kHeap, arr[i], i);
21         }
22         for (int i = k; i != arr.length; i++) {
23             if (arr[i] < kHeap[0]) {
24                 kHeap[0] = arr[i];
25                 heapify(kHeap, 0, k);
26             }
27         }
28         return kHeap;
29     }
30
31     // 建堆的过程
32     private void heapInsert(int[] arr, int value, int index) {
33
34         arr[index] = value;
35         while (index != 0) {
36             int parent = (index - 1) / 2;
37             if (arr[parent] < arr[index]) {
38                 swap(arr, parent, index);
39                 index = parent;
40             } else {
41                 break;
42             }
43         }
44     }
45
46     // 调整堆的过程
47     private void heapify(int[] arr, int index, int heapSize) {
48
49         int left = index * 2 + 1;
50         int right = index * 2 + 2;
51         int largest = index;
52         while (left < heapSize) {
53             if (arr[left] > arr[index]) {
54                 largest = left;
55             }
56             if (right < heapSize && arr[right] > arr[largest]) {
57                 largest = right;
58             }
59             if (largest != index) {
60                 swap(arr, largest, index);
61             } else {
62                 break;
63             }
64             index = largest;
65             left = index * 2 + 1;
66             right = index * 2 + 2;
67         }
68     }
69
70     // 交换
71     public void swap(int[] arr, int index1, int index2) {
72         int tmp = arr[index1];
73         arr[index1] = arr[index2];
74         arr[index2] = tmp;
75     }
76 }
时间: 2024-08-14 23:33:36

【算法】数组与矩阵问题——找到无序数组中最小的k个数的相关文章

[程序员代码面试指南]数组和矩阵问题-找到无序数组中最小的k个数(堆排序)

题目链接 https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&tqId=11182&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述 从无序序列,找到最小topk个元素. 解题思路 使用大根堆维护最小topk个元素: - 首先前k个元素建立大根堆(从

找到无序数组中最小的k个数

题目:给定一个无序整数数组arr,找到其中最小的k个数 要求:如果数组arr的长度为n,排序之后自然可以得到最小的k个数,此时时间复杂度与排序的时间复杂度相同均为O(NlogN),本题要求实现时间复杂度为O(NLogK). 1.O(NLogK)的方法,即一直维护一个有k个数的最大的大根堆,这个堆是目前选出的k个最小数,在堆里的k个元素中堆顶的元素是最大的一个. 接下来遍历整个数组,遍历的过程中看当前数是否比堆顶元素小.如果是,就把堆顶的元素替换成当前的数,然后从堆顶的位置调整堆,替换后堆的最大元

小米笔试题:无序数组中最小的k个数

题目描述 链接:https://www.nowcoder.com/questionTerminal/ec2575fb877d41c9a33d9bab2694ba47?source=relative 来源:牛客网 无序数组中最小的k个数 对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数,顺序与原数组中元素顺序一致. 给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数. 测试样例: [1,2,4,3],4,2 返回:[1,2] 代码 需要保留K个较小的元素,可以删

算法题:求数组中最小的k个数

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:输入n个整数,找出其中最小的k个数. <剑指offer>给出了两种实现算法: 算法1:采用Partition+递归法,该算法可以说是快速排序和二分查找的有机结合.算法的时间复杂度为O(n),缺点在于在修改Partition的过程中会修改原数组的值. 算法2:采用top-k算法.如果要找最小的K个数,我们才用一个含有K个值的大顶堆:如果要找最大的K个数,我们采用小顶堆.该算法的时间复杂度为O(nlogK),是一种比较好的算法,启发于堆排序

数组中最小的K个数

思路:1.排序,取前k个元素:O(NlogN):2.分治,O(n),利用快排的思想:3.用set 维护最小的k个数,O(NlogK),可处理海量数据. #include <iostream> using namespace std; void print(int *a,int n){ if(a==NULL || n<=0 ) return; for(int i=0;i<n;i++){ cout<<a[i]<<" "; } cout<

找到n中最小的k个数

题目:n个数中,求最小的前k个数. 这道题在各个地方都看到过,在国内出现的频率也非常高. 解法: 1. brute force. O(k*n)复杂度: 2. sort.O(k+n*lgn)复杂度: 3. 最大堆.每次替代的是大小为k的最大堆的最大值.O(k+(n-k)lgk)复杂度. 4. 最小堆.和sort类似,只是建堆后只求前k次.O(n+k*lgn)复杂度.在网上看到一个优化,就是pop出第k小的数(堆顶)的时候,最多只需要调整k-1层(不需要调到堆底).所以可以优化到O(n+k^2).当

8.4 找到无序数组中最小的k个数

[题目]: 给定一个无序的整型数组arr,找到其中最小的k个数 [要求]: 如果数组arr的长度为N,排序之后自然可以得到最小的k个数,此时时间复杂度与排序的时间复杂度相同,均为O(NlogN).本题要求读者实现时间复杂度为O(Nlogk)和O(N)的方法 原文地址:https://www.cnblogs.com/latup/p/9982499.html

求数组中最小的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 { /** * 基于优先队列,时间复杂度为

求一个数组中最小的K个数

方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如果大于最大元素则忽略,如果小于最大元素则将次元素送入堆中,并将堆的最大元素删除,调整堆的结构; 方法3:使用复杂度为O(n)的快速选择算法..................... /** * Created by elvalad on 2014/12/8. * 输入N个整数,输出最小的K个 */ impor