题目描述:
示例:
题目分析:
- 求数组中最小的k个数
- 可以以任意顺序返回,即是返回的最小k个数可以是无序的
思路一:
先对数组进行排序,然后再返回前k个数.
class Solution {
public int[] smallestK(int[] arr, int k) {
int[] result = new int[k];
int len = arr.length;
if (len == 0 || k == 0) return new int[0];
Arrays.sort(arr);
for (int i = 0; i < k; i++) {
result[i] = arr[i];
}
return result;
}
}
思路二:
使用冒泡排序对数组进行排序,因为冒泡过程中,每一轮对比都会确定一个最小数(最大数),因此只需要冒k次,即可获得最小的前k个数。(超时:java的Arrays.sort默认使用快排,大量数据会使用归并,因此反而不会超时)
代码实现:
class Solution {
public int[] smallestK(int[] arr, int k) {
int[] result = new int[k];
int len = arr.length;
if (len == 0 || k == 0) return new int[0];
for (int i = 0; i < k; i++) {
int j = 0;
for (; j < len - i - 1; j++) {
if (arr[j] < arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
result[i] = arr[j];
}
return result;
}
}
思路三:
使用快速排序,因为快排每次都会将数据分为大于基准数小于等于基准数两部分,那么我们只需要在快速排序的过程中,最小的前k个数必然会被分到索引k的左边(从小到大排序),因此在这个过程中,不停的丢弃k右边的数,知道基准坐标等于k-1(索引从0开始),那么0到k-1就是要求的数了。
代码实现:
class Solution {
public int[] nums;
public int k;
public int[] smallestK(int[] arr, int k_) {
k = k_;
nums = arr;
int[] result = new int[k];
int len = arr.length;
if (k == 0 || len == 0) return new int[0];
quickSort(0, len - 1);
for (int i = 0; i < k; i++) {
result[i] = arr[i];
}
return result;
}
public void quickSort(int start, int end) {
int poivt = nums[start];
int left = start;
int right = end;
while (left < right) {
while (left < right && poivt < nums[right]) {
right--;
}
while (left < right && poivt >= nums[left]) {
left++;
}
if (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
}
nums[start] = nums[left];
nums[left] = poivt;
if (left > (k - 1)) {
quickSort(start, left - 1);
}
if (left < (k - 1)) {
quickSort(left + 1, end);
}
if (left == (k - 1)) return;
}
}