寻找第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 ≤ 数组的长度。

使用分治法解决,和快速排序升序的思想接近。

设置双指针,low和high,找个基准值,使其和low中的值交换
开始从下标为left = low+1开始走,要是数组中left小于high,并且left为下标的值大于等于bound,则left继续左移,否则移动high,要是以high为下标中的值小于基准值,则右移,否则要是当前left<high,则交换Left和high中的值,并使high在左移一个单位,left右移一个单位,要是left大于right,就跳出,否则继续上述比较!

跳出循环,交换最后right和low为下标的数组元素的值。
并返回此前right的值。right右边的都是比基准值大的,左边的都是比基准值小的。
right为当前基准值的下标
判断当前基准值的下标和指定的元素位次,要是比位次大,使high=right-1
要是相等的话,就返回right
要是位次小于right的话,使low=right+1

具体实现源代码:

#include <iostream>
#include <vector>
using namespace std ;

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        vector<int> ls(nums.size()) ;
        int low = 0 ;
        int high = nums.size()-1 ;    
        int mid = 0 ;
        while(low <= high) {
            mid = partition(low, high, nums) ;
            if(mid == k-1) {
                return nums[mid] ;
            }
            if(mid < k-1) {
                low = mid+1 ;
            }
            if(mid > k-1) {
                high = mid-1 ;
            }
        }
        return -1 ;
    }

    int partition(int low , int high, vector<int>&nums) {
        int left = low+1;
        int right = high ;
        swap(nums[low], nums[(high+low)/2]) ;
        int bound = nums[low] ;
        while(left <= right) {
            while(left < high && nums[left] >= bound) left++ ;
            while(nums[right] < bound) right-- ;
            if(left < right) {
                swap(nums[right--], nums[left++]) ;
            }
            else break ;
        }
        swap(nums[low], nums[right]) ;
        return right ;
    }

    void swap(int& l1, int& l2) {
        int tmp = l1 ;
        l1 = l2 ;
        l2 = tmp ;
    }
};

int main() {
    vector<int> ls ;
    while(1) {
        int a ;
        cin >> a ;
        if(a == -1) break ;
        ls.push_back(a) ;
    }
    Solution ss ;
    int num ;
    cin >> num ;
    cout << ss.findKthLargest(ls, num) << endl ;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值