最小的k个数(Java实现)

来源:互联网 发布:unity3d 导入 box 编辑:程序博客网 时间:2024/06/15 12:44

本题为剑指offer面试题30


牛客网测试地址:https://www.nowcoder.com/questionTerminal/6a296eb82cf844ca8539b57c23e6e9bf


[编程题]最小的K个数
  • 热度指数:88997    时间限制:1秒    空间限制:32768K
  • 算法知识视频讲解
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

代码如下:

package go.jacob.day506;import java.util.ArrayList;import java.util.Stack;/** * @author Administrator * 用最小堆实现 * 思路:建立一个最大堆,堆大小为k。当堆不满时,直接插入元素; *      当堆满,将插入元素k与堆中最大元素max比较,如果k<max,将max替换为k,否则不操作。 */public class Demo2 {ArrayList<Integer> list = new ArrayList<Integer>();public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {//鲁棒性判断if (input == null || k <= 0 || k > input.length)return list;MaxPQ q = new MaxPQ(k);//最小堆插入元素O(log(n))for (int i = 0; i < input.length; i++) {q.insert(input[i]);}//用堆栈堆元素进行反序Stack<Integer> stack = new Stack<Integer>();while (q.size > 0) {stack.push(q.delMax());}while (!stack.isEmpty()) {list.add(stack.pop());}return list;}}/* * 最大堆 */class MaxPQ {int[] arr = null;int size = 0;int maxNum = 0;//数组下标从1开始public MaxPQ(int maxNum) {arr = new int[maxNum + 1];this.maxNum = maxNum;}//删除最大元素public int delMax() {if (size <= 0)throw new RuntimeException("堆空");if (size == 1) {size--;return arr[1];}int max = arr[1];arr[1] = arr[size--];sink(1);return max;}//插入元素public void insert(int v) {if (size < maxNum) {arr[++size] = v;swim(size);} else {if (arr[1] > v) {arr[1] = v;sink(1);}}}//下沉private void sink(int k) {while (k * 2 <= size) {int child = k * 2;if (child < size) {if (arr[child] < arr[child + 1])child++;}if (arr[k] < arr[child]) {exch(arr, k, child);k = child;} elsebreak;}}//上浮private void swim(int k) {arr[0] = arr[k];while (arr[k] > arr[k / 2]) {exch(arr, k, k / 2);k = k / 2;}}private void exch(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}}



0 0
原创粉丝点击