LeetCode 215 Kth Largest Element in an Array

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

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.

思路:
  1. 选取数组合适的element作为pivot  (提高效率)
  2. 使用partition,elements<=pivot的放到pivot前,elements>=pivot的elements放到pivot后,pivot就放到了正确位置position。
  3. 缩小下次partition查找的范围。如果pivot的position比target大,那么扔掉pivot之后的elements,继续在pivot之前的elements里面找。反之,pivot的position小于target,扔掉pivot之前的elements,再pivot之后的elements里继续partition。这样不断缩小,一直到不能再缩小。
  4. nums[target] 就是 the kth distinct element。
1ms Java solution beats 99.1%.
	public int findKthLargest(int[] nums, int k) {
		int n = nums.length, target = n - k;
		quicksort(nums, 0, n - 1, target);
		return nums[n - k]; //nums[n - k]就是the kth largest element
	}


	private void quicksort(int[] nums, int start, int end, int target) {
		if (start >= end) return;
		int mid = start + (end - start) / 2;
		int pivot = choosePivot(nums[mid], nums[start], nums[end]);
		int i = start, j = end;
		while (i <= j) {
			while (nums[i] < pivot) i++;
			while (nums[j] > pivot) j--;
			if (i <= j) {
				if (nums[i] != nums[j]) swap(nums, i, j);
				i++;
				j--;
			}
		}
		if (target <= i - 1) quicksort(nums, start, i - 1, target);
		else quicksort(nums, i, end, target);
	}

	/**选取a,b,c三者的中位数*/
	private int choosePivot(int a, int b, int c) {
		int min = Math.min(a, Math.min(b, c));
		int max = Math.max(a, Math.max(b, c));
		return a - max + b - min + c;
	}

	private void swap(int[] nums, int i, int j) {
		int tmp = nums[i];
		nums[i] = nums[j];
		nums[j] = tmp;
	}
思路:
使用优先队列,维护size为k的小顶堆,堆顶的元素就是第k大的元素,而其余元素都比这个元素大。
9ms Java solution beats 66.46%.
	public int findKthLargest2(int[] nums, int k) {
		PriorityQueue<Integer> pq = new PriorityQueue<Integer>(k);
		for (int i = 0; i < nums.length; i++) {
			if (pq.size() < k) pq.offer(nums[i]);
			else if (nums[i] > pq.peek()) {
				pq.poll();
				pq.offer(nums[i]);
			}
		}
		return pq.peek();
	}
总结:一般快排的话,选取pivot的时候,不能每次只选第一个或者最后一个,可以选第一个或中间的或最后一个,最好选三者中排名第二大的;或者选取pivot之前,将无序数组进行shuffle也是不错的办法,但是效果还是前者更好。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值