演算法題(二十六)利用堆排序解決找出最小的k個值問題
阿新 • • 發佈:2018-12-19
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
分析
問題很簡單,升序排序後直接輸出前k個,不過要考慮時間複雜度的問題。可以用堆排序,構建有k個值的大頂堆,然後用堆頭部與其他值比較,堆頭部值較大則調換值,並調整,最後k個值為最小的幾個。時間複雜度為nlogk。
程式碼
import java.util.ArrayList; public class HeapKthMin { public static void main(String[] args) { // TODO Auto-generated method stub int[] nums = {6,7,5,1,9,8,2,3,4}; ArrayList<Integer> list = getLeastNumber(nums, 5); for(int num: list){ System.out.println(num); } } public static ArrayList<Integer> getLeastNumber(int[] input, int k){ ArrayList<Integer> res = new ArrayList<>(); if(input==null || input.length==0 || input.length<k){ return res; } for(int i=k/2-1; i>=0; i--){ adjustHeap(input, i, k-1); } for(int i=k; i<input.length; i++){ if(input[i] < input[0]){ int temp = input[i]; input[i] = input[0]; input[0] = temp; adjustHeap(input, 0, k-1); } } for(int i=0; i<k; i++){ res.add(input[i]); } return res; } public static void adjustHeap(int[] nums, int position, int length){ int temp = nums[position]; int child = 2*position+1; for(; child<=length; child=child*2+1){ if(child<length && nums[child]<nums[child+1]){ child++; } if(temp>nums[child]){ break; } nums[position] = nums[child]; position = child; } nums[position] = temp; } }