0
点赞
收藏
分享

微信扫一扫

面试题 17.14. 最小K个数

ITWYY 2021-09-21 阅读 140
今日算法
题目描述:
示例:
题目分析:
  • 求数组中最小的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;
    }
}
举报

相关推荐

面试题 04.02. 最小高度树

0 条评论