• 最小的K个数
    • 题目
    • 解题思路
      • Partition
      • 小根堆算法

    最小的K个数

    题目

    牛客网

    输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,

    解题思路

    Partition

    该算法基于 Partition

    1. public ArrayList<Integer> GetLeastNumbers_Solution_Partition(int[] input, int k) {
    2. ArrayList<Integer> res = new ArrayList<>();
    3. if (k > input.length || k < 1) {
    4. return res;
    5. }
    6. int start = 0, end = input.length - 1;
    7. int index = partition(input, start, end);
    8. while (index != k - 1) {
    9. if (index > k - 1) {
    10. end = index - 1;
    11. index = partition(input, start, end);
    12. } else {
    13. start = index + 1;
    14. index = partition(input, start, end);
    15. }
    16. }
    17. for (int i = 0; i < input.length && i < k; i++) {
    18. res.add(input[i]);
    19. }
    20. return res;
    21. }
    22. private int partition(int[] nums, int start, int end) {
    23. int left = start, right = end;
    24. int key = nums[left];
    25. while (left < right) {
    26. while (left < right && nums[right] > key) {
    27. right--;
    28. }
    29. if (left < right) {
    30. nums[left] = nums[right];
    31. left++;
    32. }
    33. while (left < right && nums[left] <= key) {
    34. left++;
    35. }
    36. if (left < right) {
    37. nums[right] = nums[left];
    38. right++;
    39. }
    40. }
    41. nums[left] = key;
    42. return left;
    43. }

    小根堆算法

    该算法基于小根堆,适合海量数据,时间复杂度为:n*logk

    1. public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
    2. ArrayList<Integer> res = new ArrayList<>();
    3. if (k > input.length||k==0) {
    4. return res;
    5. }
    6. for (int i = input.length - 1; i >= 0; i--) {
    7. minHeap(input, 0, i);
    8. swap(input, 0, i);
    9. res.add(input[i]);
    10. if (res.size() == k) break;
    11. }
    12. return res;
    13. }
    14. private void minHeap(int[] heap, int start, int end) {
    15. if (start == end) {
    16. return;
    17. }
    18. int childLeft = start * 2 + 1;
    19. int childRight = childLeft + 1;
    20. if (childLeft <= end) {
    21. minHeap(heap, childLeft, end);
    22. if (heap[childLeft] < heap[start]) {
    23. swap(heap, start, childLeft);
    24. }
    25. }
    26. if (childRight <= end) {
    27. minHeap(heap, childRight, end);
    28. if (heap[childRight] < heap[start]) {
    29. swap(heap, start, childRight);
    30. }
    31. }
    32. }
    33. private void swap(int[] nums, int a, int b) {
    34. int t = nums[a];
    35. nums[a] = nums[b];
    36. nums[b] = t;
    37. }