分而治之——Kth Largest Element in an Array

来源:互联网 发布:2个excel表格数据比对 编辑:程序博客网 时间:2024/06/05 04:07

问题描述:

找到未排序数组中的第k个最大元素。注意,它是排序顺序中的第k个最大元素,而不是第k个不同元素。

解题思路:

可以直接调用sort函数来给数组排序,从而得到第k个最大元素。然而实际上,我们并不需要对整个数组进行排序。过程如下:我们可以任取数组中的一个元素,并以它为主元将原来的数组划分为3个部分,第一个部分是大于主元的,第二个部分是等于主元的,第三个部分是小于主元的。当然,这三个部分不一定有序。然后,我们判断第k个最大元素应该在哪个部分中,然后对那个部分继续这个过程。

将上述算法改写成代码的时候,比较难的部分是如何将数组划分为3个部分。下面的代码和快排的代码很像,思路也是如出一辙。先将数组分为>pivot和<=pivot两个部分,然后再从尾部开始进行一次划分,将<pivot的元素都放在靠近数组尾部的位置。这样一来,数组就被划分为了>pivot,=pivot,<pivot三个部分。

源代码如下:

class Solution {

public:

   int helpFindKthLargest(vector<int>& nums, int k,int begin,intend)

    {

       int last_big=begin;

       int pivot=nums[(begin+end)/2];

       int c1=0;

       swap(nums[begin],nums[(begin+end)/2]);

       for(int i=begin+1;i<=end;i++)

       {

           if(nums[i]>pivot)

           {

                swap(nums[i],nums[last_big+1]);

                last_big++;

                c1++;

           }

       }

       swap(nums[begin],nums[last_big]);

       int last_small=end;

       int c3=0;

       swap(nums[end],nums[last_big]);

       for(int i=last_small-1;i>=begin;i--)

       {

           if(nums[i]<pivot)

           {

               swap(nums[i],nums[last_small-1]);

                last_small--;

                c3++;

           }

       }

       swap(nums[end],nums[last_small]);

       int c2=end-begin+1-c1-c3;

       

       if(k<=c1) return helpFindKthLargest(nums,k,begin,c1+begin-1);

       else if(k<=(c1+c2)) return pivot;

       else return helpFindKthLargest(nums,k-c1-c2,end+1-c3,end);

    }

   int findKthLargest(vector<int>& nums,int k)

    {

       return helpFindKthLargest(nums,k,0,nums.size()-1);

    }

};

0 0
原创粉丝点击