find the Kth Largest number

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

相關文章
相關標籤/搜索