算法设计与应用基础: 第三周(3)

215. Kth Largest Element in an Array

  • Total Accepted: 116543
  • Total Submissions: 305431
  • Difficulty: Medium
  • Contributors: Admin

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.


解题过程:第二次遇到这个题了,上次是在学数据结构的时候,Ta留的作业中(有一些细微的差别,那道题是要输出前K大的数,不过思路都是一样的)。对于快速排序,总是感觉掌握的不牢,所以遇到可以用快排的题,还是要好好做一做。首先回忆快排的基本思路,每次找一个partition(这里默认partition就是数组首元素),然后从数组的开头和结尾分别扫描(first和last分别代表小于等于partition的第一个元素下标和最后一个元素下标),直到first=last,这时位于partition(也就是nums[first]=nums[last])之前的都比它小,位于它之后的都比它大。主要代码如下

 while(first<last)

    {

        while(first<last&&nums[last]<=key) last--;

        nums[first]=nums[last];

        while(first<last&&nums[first]>=key) first++;

        nums[last]=nums[first];

    }

两个while循环代表两个扫描(这也是我认为的快排的代码核心)。

然后就是处理本道题的思路,判断位于partition之前的元素是否大于K-1:1.若大于,则第K大的一定位于partition之前,此时对前部分元素继续用快排;2.若等于,则partition就是所求答案;3.若小于,则第K大的一定位于partition之后,对后部分元素用快排

这也就是divide and conquer思想

代码如下

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        return binary_search(nums, k,0,nums.size()-1);
    }
private:
    int binary_search(vector<int>& nums,int k,int low,int high)
    {
        int first=low,last=high;
        int key=nums[first];
        while(first<last)
        {
            while(first<last&&nums[last]<=key) last--;
            nums[first]=nums[last];
            while(first<last&&nums[first]>=key) first++;
            nums[last]=nums[first];
        }
        nums[first]=key;
        if((first-low)+1>k) return binary_search(nums,k,low,first-1);
        else if((first-low)+1==k) return key;
        else return binary_search(nums,k-((first-low)+1),first+1,high);
    }
};

复杂度分析:

因为快排每次将数组划分为两组加一个枢纽元素,每一趟划分你只需要将k与枢纽元素的下标进行比较,如果比枢纽元素下标大就从右边的子数组中找,如果比枢纽元素下标小从左边的子数组中找,如果一样则就是枢纽元素,找到,如果需要从左边或者右边的子数组中再查找的话,只需要递归一边查找即可,无需像快排一样两边都需要递归,所以复杂度必然降低。

最差情况如下:假设快排每次都平均划分,但是都不在枢纽元素上找到第k大

第一趟快排没找到,时间复杂度为O(n),第二趟也没找到,时间复杂度为O(n/2),。。。。。,第k趟找到,时间复杂度为O(n/2k),所以总的时间复杂度为

O(n(1+1/2+....+1/2k))=O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值