剑指Offer8
最小的K个数
http://www.nowcoder.com/questionTerminal/6a296eb82cf844ca8539b57c23e6e9bf
Question
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
思路
使用堆排序的方法对数组进行排序后,取前k个最小值,这里手动实现建堆;
升序--使用大顶堆
降序--使用小顶堆
Code
import java.util.ArrayList; public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { ArrayList<Integer> res = new ArrayList<>(); if(input == null || input.length == 0 || k > input.length || k == 0) return res; //建立大顶堆 for(int i = input.length; i > 0; i--) { BuildMaxHeap(input , i); Swap(input, i); //将大值放到后面 } for(int i = 0; i < k; i++) { res.add(input[i]); } return res; } //建立大顶堆 private void BuildMaxHeap(int[] input , int len) { //从最后一个非叶子结点开始建立大顶堆 for(int i = len / 2 - 1; i >= 0; i--) { //根结点小于左子树 if((2 * i + 1) < len && input[i] < input[2 * i + 1]) { int tmp = input[i]; input[i] = input[2*i+1]; input[2*i+1] = tmp; //检查交换后左子树是否满足大顶堆性质 if(2*(2*i+1)+1< len && input[2*i+1] < input[2*i+1] || 2*(2*i+1) + 2 < len && input[2*i+1] < input[2*(2*i+1)+2]) { BuildMaxHeap(input, len); } } //根结点小于右子树 if((2*i+2) < len && input[i] < input[2*i+2]) { int tmp = input[i]; input[i] = input[2*i+2]; input[2*i+2] = tmp; if(2*(2*i+2) + 1 < len && input[2*i+2] < input[2*(2*i+2)+1] || 2*(2*i+2) + 2 < len && input[2*i+2] < input[2*(2*i+2)+2]) { BuildMaxHeap(input,len); } } } } //将根结点与最后一个元素交换位置 private void Swap(int[] input, int len) { int tmp = input[0]; input[0] = input[len-1]; input[len-1] = tmp; } }