K Smallest In Unsorted Array

Find the K smallest numbers in an unsorted integer array A. The returned numbers should be in ascending order.

Assumptions

  • A is not null
  • K is >= 0 and smaller than or equal to size of A

Return

  • an array with size K containing the K smallest numbers in ascending order

Examples

  • A = {3, 4, 1, 2, 5}, K = 3, the 3 smallest numbers are {1, 2, 3}

M1: min heap

time: O(n + klogn), space: O(1)

public class Solution {
  public int[] kSmallest(int[] array, int k) {
    // Write your solution here
    int[] res = new int[k];
    if(array == null || array.length == 0) {
      return res;
    }
    PriorityQueue<Integer> minHeap = new PriorityQueue<>();
    for(int n : array) {
      minHeap.offer(n);
    }
    for(int i = 0; i < k; i++) {
      res[i] = minHeap.poll();
    }
    return res;
  }
}

M2: max heap

time: O(k + (n-k)logk), space: O(1)

public class Solution {
  public int[] kSmallest(int[] array, int k) {
    // Write your solution here
    if(array.length == 0 || k == 0) {
      return new int[0];
    }
    PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, 
                                                         new Comparator<Integer>() {
                                                           @Override
                                                           public int compare(Integer o1, Integer o2) {
                                                             if(o1.equals(o2)) {
                                                               return 0;
                                                             }
                                                             return o1 > o2 ? -1 : 1;
                                                           }
                                                         });
    for(int i = 0; i < array.length; i++) {
      if(i < k) {
        maxHeap.offer(array[i]);
      } else if(array[i] < maxHeap.peek()) {
        maxHeap.poll();
        maxHeap.offer(array[i]);
      }
    }
    int[] res = new int[k];
    for(int i = k - 1; i >= 0; i--) {
      res[i] = maxHeap.poll();
    }
    return res;
  }
}

M3: quick select

time: O(n)  worst case O(n^2), space: O(k)

public class Solution {
  public int[] kSmallest(int[] array, int k) {
    // Write your solution here
    if(array.length == 0 || k == 0) {
      return new int[0];
    }
    quickSelect(array, 0, array.length - 1, k - 1);
    int[] res = Arrays.copyOf(array, k);
    Arrays.sort(res);
    return res;
  }
  
  private void quickSelect(int[] array, int left, int right, int target) {
    int mid = partition(array, left, right);
    if(mid == target) {
      return;
    } else if(mid < target) {
      quickSelect(array, mid + 1, right, target);
    } else {
      quickSelect(array, left, mid - 1, target);
    }
  }
  
  private int partition(int[] array, int left, int right) {
    int pivot = array[right];
    int start = left, end = right - 1;
    while(start <= end) {
      if(array[start] < pivot) {
        start++;
      } else if(array[end] >= pivot) {
        end--;
      } else {
        swap(array, start++, end--);
      }
    }
    swap(array, start, right);
    return start;
  }
  
  private void swap(int[] array, int i, int j) {
    int tmp = array[i];
    array[i] = array[j];
    array[j] = tmp;
  }
}
原文地址:https://www.cnblogs.com/fatttcat/p/10267719.html