1.题目描述
面试题 17.14. 最小K个数
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
1 2
| 输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3,4]
|
提示:
0 <= len(arr) <= 100000
0 <= k <= min(100000, len(arr))
2.代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| class Solution { /** * leetcode 面试题 17.14. 最小K个数 * @param arr * @param k * @return */ public static int[] smallestK(int[] arr, int k) { if (arr.length == 0){ return new int[]{}; } //排序 mergeSort(arr,0, arr.length-1);
//返回最小的k个数 int[] temp = new int[k]; for (int i = 0; i < k; i++) { temp[i] = arr[i]; }
return temp; }
/** * 归并排序 递归 * @param nums * @param start * @param end */ public static void mergeSort(int[] nums,int start,int end){ //只要划分的区间长度仍然不为1 if (start != end){ int middle = (start+end) / 2;
//分 mergeSort(nums,start,middle); mergeSort(nums,middle+1,end);
//治 merge(nums,start,end,middle); } }
/** * 归并 * @param nums * @param start * @param end * @param middle */ public static void merge(int[] nums,int start,int end,int middle){ //模拟第一个序列的头指针 int i = start;
//模拟第二个序列的头指针 int j = middle+1;
//模拟临时数组的头指针 int t = 0;
//创建临时数组 int[] temp = new int[end-start+1];
//从头比较两个序列,小的放入临时数组temp while (i <= middle && j <= end){ //比较大小 if (nums[i] < nums[j]){ //前一个序列 temp[t++] = nums[i++]; }else { //后一个序列 temp[t++] = nums[j++]; } }
//单独处理没有处理完的第一个序列 while (i <= middle){ temp[t++] = nums[i++]; }
//单独处理没有处理完的第二个序列 while (j <= end){ temp[t++] = nums[j++]; }
//将临时数组的值赋值到原数组 for (int p = 0; p < temp.length; p++) { nums[start+p] = temp[p]; } } }
|