1.题目描述
面试题 17.14. 最小K个数
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
| 12
 
 | 输入: 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.代码实现
| 12
 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];
 }
 }
 }
 
 |