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

万能的最小堆思路。

  • 用最小堆,堆中保存的是$k$个最大的元素。
  • 用最大堆,堆中保存的是$n-k+1$个最小的元素。

C++代码实现:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {

    	int n = nums.size();
    	if(k < 1 || n < k)
    		return INT_MIN;
        //用最小堆还是最大堆,主要是为了确保我们最终要得到的元素位于堆顶,可以直接取出,
        //这时可以看一看堆顶元素在堆中元素中是最大的,还是最小的
        //其实这个问题还可以使用最大堆,堆中的元素为最小的n-k+1个元素,则最大堆的堆顶元素即
        //为第n-k+1小元素(也就是第k大元素),但是一般来说,k<<n,所以为了节约堆的空间大小,这里
        //我们使用最小堆
    	priority_queue<int,vector<int>,greater<int>> q;//最小堆
    	for(int i = 0;i < n;i++)
    	{
    		if(i < k)
    			q.push(nums[i]);
    		else
    		{
    			int temp = q.top();
    			if(nums[i] > temp)
    			{
    				q.pop();
    				q.push(nums[i]);
    			}
    		}
    	}
    	return q.top();        
    }
};

 java代码实现

class Solution {
    public int findKthLargest(int[] nums, int k) {
        if(nums.length==0 || k>nums.length)
        return Integer.MIN_VALUE;
       PriorityQueue<Integer> prq = new PriorityQueue();
       for(int i = 0;i<nums.length;i++){
           if(i<k)
               prq.offer(nums[i]);
           else{
               int the_min = prq.peek();
               //确保这个最小堆中始终持有k个最大的数
               if(nums[i]>the_min){
                   prq.poll();
                   prq.offer(nums[i]);

               }
           }
       }
       return prq.peek();
    }
}

 利用快排的思想

C++代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

int partition(vector<int> &nums, int start, int end)
{
    if (start == end)
        return start;
    int pivot = nums[end];
    int i = start - 1, j = end;
    while (true)
    {
        while (nums[++i] > pivot)
        {
            if (i == end)
                break;
        }
        while (nums[--j] < pivot)
        {
            if (j == start)
                break;
        }
        if (i < j)
            swap(nums[i], nums[j]);
        else
            break;
    }
    swap(nums[end], nums[i]);
    return i;
}

int find_kth_max(vector<int> &nums, int k)
{
    int n = nums.size();
    if (n == 0 || n < k)
        return INT_MIN;
    int left = 0, right = n - 1;
    while (left <= right)
    {
        int index = partition(nums, left, right);
        cout << "the index is:" << index << " " << endl;
        if (index == k - 1)
            return nums[k - 1];
        else if (index < k - 1)
            left = index + 1;
        else
            right = index - 1;
    }
    return INT_MIN;
}

int main()
{
    vector<int> nums = {3, 2, 3, 1, 2, 4, 5, 5, 6};
    int ret = find_kth_max(nums, 4);
    cout << "\nthe kth max value is :" << ret << endl;
    return 0;
}

 java代码实现

class Solution {
    public int findKthLargest(int[] nums, int k) {
        if(nums.length==0 || k>nums.length)
            return Integer.MIN_VALUE;
        int start = 0;
        int end = nums.length - 1;
        int index = partition(nums,start, end);
        //循环前循环用到的变量进行的变量初始值操作
        while(index != k-1)
        {
            if(index > k-1)
            {
                end = index-1;
                index = partition(nums,start, end);
            }
            else
            {
                start = index + 1;
                index = partition(nums,start, end);
            }
        }
        return nums[k-1];
        
    }
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static int partition(int[] nums, int left, int right){

    if(left==right)
        return left;
    int pivot = nums[left];
    int i = left;
    int j = right+1;
    while(true){
        while(nums[++i]>pivot){
            if(i==right)
                break;
        }
        while(nums[--j]<pivot){
            if(j==left)
                break;
        }
        if(i<j){
            swap(nums,i,j);
 
        }
        else
            break;
    }
    swap(nums,left,j);
    return j;
 
}
 

}

  

  

posted on 2022-02-27 18:11  朴素贝叶斯  阅读(60)  评论(0编辑  收藏  举报

导航