找第k大的数

1、两个有序数组中第k大的数

   int findKth(vector<int> nums1, vector<int> nums2, int k){
		int s1 = nums1.size();
		int s2 = nums2.size();
		if (s1 > s2)
			return findKth(nums2, nums1, k);
		if (s1 == 0)
			return nums2[k - 1];
		if (k == 1)
			return min(nums1[0], nums2[0]);
		int i = min(k / 2, s1), j = k - i;
		if (nums1[i - 1] < nums2[j - 1])
			return findKth(vector<int>(nums1.begin() + i, nums1.end()), nums2, k - i);
		else if (nums1[i - 1] > nums2[j - 1])
			return findKth(nums1, vector<int>(nums2.begin() + j, nums2.end()), k - j);
		else
			return nums1[i - 1];

	}

2、在N个乱序数组中查找第k大的数

不对前K个数进行排序 + 不对N-k个数排序,可以使用

思路:寻找第K个大元素。

具体方法:使用类似快速排序执行一次快速排序后,每次只选择一部分继续执行快速排序,直到找到第K个大元素为止,此时这个元素在数组位置后面的元素即所求

时间复杂度:

       若随机选取枢纽,线性期望时间O(N)

       若选取数组的“中位数的中位数”作为枢纽,最坏情况下的时间复杂度O(N)

      利用快速排序的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况:

           1. Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
           2. Sa中元素的个数大于等于k,则返回Sa中的第k大数。
          利用快排的partion思想 T(n) = 2T(n/2) + O(1)   时间复杂度为O(n)   
          该方法只有当我们可以修改输入的数组时可用,位于数组左边的k个数字就是最小的k个数字(但这k个数字不一定是排序的),位于第k个数右边的数字都比第k个数字大
#include<iostream>  
#include<stdio.h>  
using namespace std;  
  
int Partition (int *L, int low, int high)  
{  
    int temp = L[low];  
    int pt   = L[low]; //哨兵  
    while (low != high)  
    {  
        while (low < high && L[high] >= pt)  
            high--;  
        L[low] = L[high];         
          
        while (low < high && L[low] <= pt)  
            low++;  
        L[high] = L[low];  
    }     
    L[low] = temp;  
    return low;  
}  
  
void QSort (int *L, int low, int high)  //快速排序  
{  
    int pl;  
    if (low < high)  
    {  
        pl = Partition (L,low,high);  
        QSort (L, low,  pl-1);  
        QSort (L, pl+1, high);  
    }  
}  
  
void findk(int k,int *L,int low,int high)  
{  
    int temp;  
    temp=Partition(L,low,high);  
    if(temp==k-1)  
    {  
        cout<<"第"<<temp+1<<"大的数是:"<<L[temp]<<endl;  
    }  
    else if(temp>k-1)  
        findk(k,L,low,temp-1);  
    else  
        findk(k,L,temp+1,high);  
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值