TopK问题 - 随机选择算法

主要还是基于快排思想的二分查找 - 减治法:

  • 分治法
    分治法(Divide&Conquer),把一个大的问题,转化为若干个子问题(Divide),每个子问题“都”解决,大的问题便随之解决(Conquer)。这里的关键词是“都”。快速排序递归时,先通过partition把数组分隔为两个部分,两个部分“都”要再次递归。

分治法有一个特例,叫减治法。

  • 减治法
    减治法(Reduce&Conquer),把一个大的问题,转化为若干个子问题(Reduce),这些子问题中“只”解决一个,大的问题便随之解决(Conquer)。这里的关键词是“只”递归一个分支即可。
/*选出第K大的数*/
#include <iostream>

using namespace std;
 
int partition(int a[], int low, int high) //划分  
{  
    int pivotKey = a[low];  
    while(low < high)  
    {  
        while(low < high && a[high] >= pivotKey)  
        {
           high--;  
        }
 
        a[low] = a[high];  
 
        while(low < high && a[low] <= pivotKey)
        {
            low++;  
        }
 
        a[high] = a[low];  
    }  
 
    a[low] = pivotKey; //恢复
  
    return low;  
}
 
// 找第i个最小的值
int randomSelect(int *a, int low, int high, int i)
{
    if(low == high)
    {
        return a[low];
    }
 
    int pivot = partition(a, low, high); 
    int k = pivot - low + 1; 
 
    if(k == i) // 刚好划出来了
    {
        return a[pivot];
    }
  
    if(i < k) // 缩小范围进行递归
    {
        return randomSelect(a, low, pivot - 1, i);
    }
 
    return randomSelect(a, pivot + 1, high, i - k); // 缩小范围进行递归
}
 
int main()
{
    int a[] = {2, 5, 3, 1, 4, 111, 55};
    int n = sizeof(a) / sizeof(a[0]);
 
    int i = 6;
    cout << randomSelect(a, 0, n - 1, i) << " " << endl; // 第i个最小值
 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值