Lintcode: Kth largest Element

本文介绍了一种改进的快速选择算法,用于高效查找数组中第K大的元素,实现O(n)时间复杂度和O(1)空间复杂度。通过详细解释算法逻辑并提供关键代码注释,旨在帮助开发者理解快速选择算法的核心思想及其在实际应用中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Find K-th largest element in an array.

Note
You can swap elements in the array

Example
In array [9,3,2,4,8], the 3rd largest element is 4

In array [1,2,3,4,5], the 1st largest element is 5, 2nd largest element is 4, 3rd largest element is 3 and etc.

Challenge
O(n) time, O(1) space

使用改进的Quicksort partition,可以达到O(n)的时间复杂度,并且不需要额外空间。

请参考: http://en.wikipedia.org/wiki/Quickselect#Time_complexity

 Quickselect uses the same overall approach as quicksort, choosing one element as a pivot and partitioning the data in two based on the pivot, accordingly as less than or greater than the pivot. However, instead of recursing into both sides, as in quicksort, quickselect only recurses into one side – the side with the element it is searching for. This reduces the average complexity from O(n log n) (in quicksort) to O(n) (in quickselect).

下面这个code几个注意的地方:

1. 第8行Kth largest element = len-K+1 th smallest element

2. 第24行,l、r在相遇之后,l 所处的位置就是第一个大于等于pivot元素所在位置,把它跟pivot交换,pivot就放在了它应该在的位置

 1 class Solution {
 2     //param k : description of k
 3     //param numbers : array of numbers
 4     //return: description of return
 5     public int kthLargestElement(int k, ArrayList<Integer> numbers) {
 6         // write your code here
 7         if (k > numbers.size()) return 0;
 8         return helper(numbers.size()-k+1, numbers, 0, numbers.size()-1); 
 9     }
10     
11     public int helper(int k, ArrayList<Integer> numbers, int start, int end) {
12         int l=start, r=end;
13         int pivot = end;
14         while (true) {
15             while (numbers.get(l)<numbers.get(pivot) && l<r) {
16                 l++;
17             }
18             while (numbers.get(r)>=numbers.get(pivot) && l<r) {
19                 r--;
20             }
21             if (l == r) break;
22             swap(numbers, l, r);
23         }
24         swap(numbers, l, end);  // l here is the first one which is bigger than pivot, swap it with the pivot
25         if (l+1 == k) return numbers.get(l);
26         else if (l+1 < k) return helper(k, numbers, l+1, end);
27         else return helper(k, numbers, start, l-1);
28     }
29     
30     public void swap(ArrayList<Integer> numbers, int l, int r) {
31         int temp = numbers.get(l);
32         numbers.set(l, numbers.get(r).intValue());
33         numbers.set(r, temp);
34     }
35 };

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值