F_G

许多问题需要说清楚就可以&&走永远比跑来的重要

导航

[Leetcode] Kth largest element in an array

这个题目使用快排。

这里涉及如何实现快排的问题。在[1]当中有一个快排的实现例子。在这里我们关注与快排的实现而不是这个问题本身,因为快排的问题解决了,这个问题就解决了

快排的思想是选择一个元素,从两边进行遍历将遇到的第一对不满足序列关系的元素进行交换。

关键是这里如何实现这种兑换

1、可以在同时找到这两个元素的时候进行交换

2、交替进行替换的策略。

比如先将左边位置left空出,从右边进行遍历找第一个小于pivot的元素以及所以right,将right位置的元素放到left处,同时将right位置空出

在从左边找第一个大于pivot的元素,当然现在left位置处的元素是小于pivot的,所以会继续left加一,直至找到一个大于等于pivot的元素或者right=left。

========================================================================================

left=0,right=num.length-1;

pivot = num[left];

while(left<right){

  while(left<right&&num[right]>=pivot) right--;

    num[left]= num[right];

  while(left<right&&num[left]<pivot)     left++;

    num[right]=num[left];

}

num[left]=pivot;

========================================================================================

我们简单分析一下代码的执行边界:

1、进入外层while循环,则开始找第一个小于pivot的元素

(1)如果在left的右侧找到,则填充到left位置处;

(2)如果没有找到,也就是说当前的元素都是大于等于pivot的;则第二个内层while循环当中由于left等于right,所以进行了自我复制,最后跳出while循环,并且在left或者right处写入pivot

(3)如果第二个while循环没有找到,也就是此时left右侧到right之间的所有元素都是小鱼pivot的,那么这是实际上已经找到了pivot插入的位置,就在刚才等待插入的right 处,算法结束。

 

 对于quick sort本身是可以使用迭代和递归两种方式实现的,这里同样的道理。

 1 public class Solution {
 2     private int quick2(int []nums,int start,int end,int k){
 3         int L =start;
 4         int R = end;
 5         while(L<R){
 6             //本身L和R在loop过程当中不能混乱的修改
 7             int left = L;
 8             int right = R;
 9             int target = nums[left];
10             while(left<right){
11                 while(left<right&&nums[right]>=target) right--;
12                 nums[left]=nums[right];
13                 while(left<right&&nums[left]<target) left++;
14                 nums[right]=nums[left];
15             }
16             nums[left]=target;
17             if(left==k-1) return target;
18             else if(left<k-1){
19                 L = left + 1;
20             }else{
21                 R = left - 1;
22             }
23         }
24         return nums[k-1];
25     }
26     private int quick(int []nums,int start,int end,int k){
27         int left =start;
28         int right = end;
29         //在下面的循环过程当中start和end不能丢失
30         int target = nums[start];
31         while(left<right){
32             while(left<right&&nums[right]>=target) right--;
33             nums[left]=nums[right];
34             while(left<right&&nums[ left]< target) left++;
35             nums[right]=nums[left];
36             //最终腾出来的是left位置
37         }
38         //所以把target放到left位置
39         nums[left]=target;
40         if(left==k-1) return target;
41         else if(left<k-1){
42             return quick(nums,left+1,end,k);
43         }else{
44             return quick(nums,start,left-1,k);
45         }
46     }
47     public int findKthLargest(int[] nums, int kk) {
48         int k = nums.length-kk+1;
49         return quick2(nums,0,nums.length-1,k);
50     }
51 }

 

[1] http://www.cnblogs.com/easonliu/p/4523941.html

posted on 2015-08-11 19:32  F_G  阅读(261)  评论(0编辑  收藏  举报