leetcode刷题215 数组中的第K个最大元素

题目

  • 在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
    示例 1:
    输入: [3,2,1,5,6,4] 和 k = 2
    输出: 5
    示例 2:
    输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
    输出: 4
    说明:
    你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

思路1:基于快排的partition思想(从大往小排)

  • 选定一个数作为基点,将小于基点数点放在左边,大于等于基数的放在右边。
  • 确定查找区域:如果左边的个数小于k,则说明第k大的数在基数右边区域。否则,则说明在左边区域。
  • 在查找区域利用partition直接找到序号为k-1的数。
//返回基数在序列的位置
    int partition(vector<int>&nums,int left,int right)
    {
        int key=nums[right];
        for(int i=left;i<right;i++)
        {
            if(nums[i]<key)
                swap(nums[left++],nums[i]);
            swap(nums[right],nums[left]);
            return left;
        }

    }
    int findKthLargest(vector<int>& nums, int k) {
        int len=nums.size(),order_k=len-k,pos,left=0,right=len-1;
        while((pos=partition(nums,left,right))!=order_k)
        {
            pos<order_k ? left=pos+1 : right=pos-1;
        }
        return nums[order_k];
    }

思路2:基于堆排序的思想。

  • 用前k个数建立最小堆,然后从 k+1个数开始,与堆顶比较,如果大,就交换,直到结束。
  • 堆里存放大数组前k个最大大元素,堆顶为第k大元素
 void HeapAdjust(vector<int>& nums,int s,int length)//调整堆的程序
    {
        int temp=nums[s];
        int child = 2*s+1;//这里因为下标从0开始,每个节点的子节点就是2s+1
        while(child<length)
        {
            if(child+1<length && nums[child]>nums[child+1])
                child++;
            if(nums[s]>nums[child])
            {
                nums[s]=nums[child];
                s=child;
                child=2*s+1;
            }
            else
                break;
            nums[s]=temp;//这里的s已经是原来的child了
        }
    }
    void BuildingHeap(vector<int>& nums,int k)//建立堆,从最后开始筛选
    {
        for(int i=(k-1)/2;i>=0;i--)
            HeapAdjust(nums,i,k);
    }
int findKthLargest(vector<int>& nums, int k)
    {
        int size=nums.size();
        if(k>size) return nums[size-1];
        vector<int> mynum;//(nums.begin(),nums.begin()+k);
        int index=0;
        for(;index<k;index++)
        {
            mynum.push_back(nums[index]);
        }

        int j=index;
        for(int i=j;i<size;i++)
        {
            if(nums[i]>mynum[0])
            {
                swap(nums[i],mynum[0]);
                HeapAdjust(mynum,0,index);
            }
        }
        return mynum[0];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值