Find the kth largest element in an unsorted array.java
For example,
Given [3,2,1,5,6,4]
and k = 2, return 5.c++
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.算法
這個題目有個直觀的解法,就是先排序(從大到小),而後在取第K個數字就能夠了,用(java,c++,c的)排序算法能夠在O(nlogn)時間裏完成;數組
可是其實並不須要全排序,從裏面選定一個數字,簡稱x,把比x大的數字放到數組S中,若是S的size爲k - 1, 那麼x就是第k大得數字;若是S的size比k - 1大,那麼只要在S中找第k大得數字;若是S的size比k - 1小,那麼就能夠從減去S的x的數組中,找k - 1 - size(S)的數字便可;ui
public class Solution { public static int qsort(int[] nums, int left, int right, int k) { if (left + 3 <= right) { int pivot = median3(nums, left, right); // int pivot = nums[right]; int i = left, j = right - 1; while (i < j) { while (nums[++i] > pivot) { } while (nums[--j] < pivot) { } if (i < j) { swap(nums, i, j); } } swap(nums, i, right - 1); if (k == i) { return nums[i]; } else if (k > i) { return qsort(nums, i + 1, right, k); } else { return qsort(nums, left, i - 1, k); } } else { insertSort(nums, left, right); return nums[k]; } } private static int median3(int[] nums, int left, int right) { int center = (left + right) / 2; if (nums[left] < nums[center]) { swap(nums, left, center); } if (nums[left] < nums[right]) { swap(nums, left, right); } if (nums[center] < nums[right]) { swap(nums, center, right); } swap(nums, center, right - 1); return nums[right - 1]; } private static void insertSort(int[] nums, int left, int right) { for (int i = left + 1; i <= right; i++) { int tmp = nums[i]; int j = i; while (j > 0 && nums[j - 1] < tmp) { nums[j] = nums[j - 1]; j -= 1; } nums[j] = tmp; } } private static void swap(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } public static int findKthLargest(int[] nums, int k) { if (nums.length == 1) { return nums[0]; } return qsort(nums, 0, nums.length - 1, k - 1); } public static void main(String[] args) { int[] nums = {3, 3, 3, 3, 3, 3, 3, 3, 3}; System.out.println(findKthLargest(nums, 8)); } }
如今通常也不會本身編寫quick sort和insert sort,會直接調用Arrays.sort,因此爲了寫這段代碼還把《Data Structures and Algorithm Analysis in C》翻出來參考。spa
如下是scala的實現,就比較straight foward了,scala
object App extends App { def qsort(list: List[Int], k: Int): Int = list match { case Nil => throw new Exception("should not get here") case h :: tail => val (left, right) = tail.partition(_ > h) if (left.size == k - 1) { h } else if (left.size > k - 1) { qsort(left, k) } else { qsort(right, k - left.size - 1) } } def findKthLargest(nums: Array[Int], k: Int) = qsort(nums.toList, k) println(findKthLargest(Array(3, 3, 3, 3, 3, 3, 3, 3, 3), 8)) println(findKthLargest(Array(3, 2, 1, 5, 6, 4), 2)) }
但大概不會java那麼高效,但表現力應該要強不少;code