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

方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn);

方法2:维护一个容量为K的最大堆(《算法导论》第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如果大于最大元素则忽略,如果小于最大元素则将次元素送入堆中,并将堆的最大元素删除,调整堆的结构;

方法3:使用复杂度为O(n)的快速选择算法.....................

/**
 * Created by elvalad on 2014/12/8.
 * 输入N个整数,输出最小的K个
 */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class MinKArray {
    /* 用二叉树表示一个堆 */
    private class Heap {
        private Node root;
        private class Node {
            int key;
            Node left;
            Node right;
            Node(int key) {
                this.key = key;
            }
        }

        /* 建立最大堆,将元素插入到堆的合适位置 */
        public void put(int key) {
            root = put(root, key);
        }

        private Node put(Node x, int key) {
            if (x == null)
                return new Node(key);
            int cmp = key - x.key;
            if (cmp > 0) {
                int tmp = x.key;
                x.key = key;
                key = tmp;
                x.right = put(x.right, key);
            } else if (cmp < 0) {
                x.left = put(x.left, key);
            }
            return x;
        }

        public void deleteMax() {
            root = deleteMax(root);
        }

        private Node deleteMax(Node x) {
            if (x == null)
                return null;
            if ((x.left == null) && (x.right != null)) {
                int tmp = x.key;
                x.right.key = x.key;
                x.key = tmp;
                x.right = deleteMax(x.right);
            } else if ((x.right == null) && (x.left != null)) {
                int tmp = x.key;
                x.left.key = x.key;
                x.key = tmp;
                x.left = deleteMax(x.left);
            } else if ((x.left == null) && (x.right == null)) {
                x = null;
            } else {
                int cmp = x.left.key - x.right.key;
                if (cmp >= 0) {
                    int tmp = x.key;
                    x.key = x.left.key;
                    x.left.key = tmp;
                    x.left = deleteMax(x.left);
                } else {
                    int tmp = x.key;
                    x.key = x.right.key;
                    x.right.key = tmp;
                    x.right = deleteMax(x.right);
                }
            }
            return x;
        }

        public void printHeap(Node x) {
            if (x == null)
                return;
            System.out.println(x.key);
            printHeap(x.left);
            printHeap(x.right);
        }
    }

    /* 使用一般的排序算法,然后顺序输出前K个元素 */
    public int[] minKArray1(int[] a, int k) {
        Arrays.sort(a);
        for (int i = 0; i < k; i++) {
            System.out.println(a[i]);
        }
        return Arrays.copyOfRange(a, 0, k);
    }

    /* O(n)算法实现快速选择算法 */
    public int[] minKArray2(int[] a, int k) {
        return a;
    }

    /* 维护一个容量为K的最大堆,《算法导论》第6章堆排序 */
    public int[] minKArray3(int[] a, int k) {
        Heap h = new Heap();
        for (int i = 0; i < k; i++) {
            h.put(a[i]);
        }
        for (int i = k; i < a.length; i++) {
            if (a[i] >= h.root.key) {
                continue;
            } else {
                h.put(a[i]);
                h.deleteMax();
            }
        }
        h.printHeap(h.root);
        return a;
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        ArrayList<Integer> array = new ArrayList<Integer>();
        while (scan.hasNext()) {
            array.add(scan.nextInt());
        }
        int[] a = new int[array.size()];
        for (int i = 0; i < a.length; i++) {
            a[i] = array.get(i);
        }
        MinKArray mka = new MinKArray();
        mka.minKArray1(a, 8);
        System.out.println("---------------");
        mka.minKArray3(a, 8);
    }
}
时间: 2024-11-03 21:34:30

求一个数组中最小的K个数的相关文章

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

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

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

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

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

1 /** 2 * 找到无序数组中最小的k个数 时间复杂度O(Nlogk) 3 * 过程: 4 * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数 5 * 在堆里的k个元素中堆顶的元素是最小的k个数中最大的那个. 6 * 2.接下来,遍历整个数组,遍历过程中看当前数是否比堆顶元素小: 7 * 如果是,就把堆顶元素替换成当前的数,然后从堆顶的位置调整整个堆,让替 8 * 换操作后堆的最大元素继续处在堆顶的位置: 9 * 如果不是,则不进行任何操作,继续遍历下一个数: 10 *

小米笔试题:无序数组中最小的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个数

public class MinHeap { /* * * Top K个问题,求给定数据中最小的K个数 * * 最小堆解决:堆顶元素为堆中最大元素 * * * */ private int MAX_DATA = 10;//最小10个数 private int[] data;//存储数据 private int len;//当前存储长度,考虑到元素个数可能没有10个,这个时候全部输出 private MinHeap() { data = new int[MAX_DATA]; len=0; } pr

数组中最小的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<

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

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

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

[程序员代码面试指南]数组和矩阵问题-找到无序数组中最小的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个元素建立大根堆(从