剑指offer_最小的k个数
题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
方法一:第一反应就是排序,选前k个
1 import java.util.*; 2 public class Solution { 3 public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { 4 ArrayList<Integer> resultList= new ArrayList<>(); 5 if(k>input.length) return resultList; 6 Arrays.sort(input); 7 int[] copyOf = Arrays.copyOf(input,k); 8 9 for(int num : copyOf){ 10 resultList.add(num); 11 } 12 return resultList; 13 } 14 }
方法二:利用快速排序的方法
快速排序的partition方法,会返回一个整数j使得a[1...j-1]小于等于a[j],且a[j+1...h]大于等于a[j],此时a[j]就是数组的第j大元素,可以利用这个特性找出数组的第K个元素,这种找第k个元素的算法被称为快速选择算法
1 import java.util.*; 2 public class Solution { 3 public ArrayList<Integer> GetLeastNumbers_Solution(int[] nums, int k) { 4 ArrayList<Integer> ret = new ArrayList<>(); 5 if (k > nums.length || k <= 0) 6 return ret; 7 findKthSmallest(nums, k - 1); 8 /* findKthSmallest 会改变数组,使得前 k 个数都是最小的 k 个数 */ 9 for (int i = 0; i < k; i++) 10 ret.add(nums[i]); 11 return ret; 12 } 13 public void findKthSmallest(int[] nums, int k) { 14 int l = 0, h = nums.length - 1; 15 while (l < h) { 16 int j = partition(nums, l, h); 17 if (j == k) 18 break; 19 if (j > k) 20 h = j - 1; 21 else 22 l = j + 1; 23 } 24 } 25 private int partition(int[] nums, int l, int h) { 26 int p = nums[l]; /* 切分元素 */ 27 int i = l, j = h + 1; 28 while (true) { 29 while (i != h && nums[++i] < p) ; 30 while (j != l && nums[--j] > p) ; 31 if (i >= j) 32 break; 33 swap(nums, i, j); 34 } 35 swap(nums, l, j); 36 return j; 37 } 38 private void swap(int[] nums, int i, int j) { 39 int t = nums[i]; 40 nums[i] = nums[j]; 41 nums[j] = t; 42 } 43 }
方法三:大顶堆
1 import java.util.*; 2 public class Solution { 3 public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { 4 if (k > input.length || k <= 0) 5 return new ArrayList<>(); 6 PriorityQueue<Integer> maxHeap = new PriorityQueue<>((o1,o2)->o2-o1); 7 for(int num : input){ 8 maxHeap.add(num); 9 if(maxHeap.size()>k) 10 maxHeap.poll(); 11 } 12 return new ArrayList<>(maxHeap); 13 } 14 }

浙公网安备 33010602011771号