find the Kth Largest number

Find the kth largest element in an unsorted array.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

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)的数字即可;

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》翻出来参考。


以下是scala的实现,就比较straight foward了,

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那么高效,但表现力应该要强很多;



转载于:https://my.oschina.net/u/922297/blog/418892

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值