寻找第N位最大值

题目意思就是在一个很大的无序数组中,找到第N位大的数

思路一:直接暴力!

利用Sort函数直接进行快排,然后把对应位数代入下标直接输出,复杂度在O(nlogn)

思路二:动态规划

定义一个大小为n的数组A[n],虽然题目上是一个很大的无序数组,但是我们可以简化来看,如果这个无序数组大小恰好为n,那么就是输出这个无序数组的最小值(第n位大,就是最小的那个值)。

现在用A[n]来存无序数组这n个数,在此基础上假设无序数组大小为n+1,现在多了一个数,那么多出来的这个数想要成为第N位大的数,那么它首先要比现在A[n]里的最小数大,否则无论如何它都进不了前N位。

所以进行判断如果第n+1个数大于A[n]里最小值,那么就替换掉这个最小值(n+1这位数替换进去后不一定是A[n]里最小的)。然后就是依次类推,n+2..n+3..,最后A[n]里的最小值就是要输出的值

思路三:分治算法

即把该无序数组分成很多个小数组,每个小数组里面找到该小数组对应的第N位大的数,然后去找所有小数组对应的第N位大的数中的第N位大的数,不过暂时没想到很好的切割方法,所以采用了动态规划。

源码:

#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
double Test[10000];   //定义测试数组

//重载swap
void swap(double* a, double* b)
{
    int temp = 0;
    temp = *a;
    *a = *b;
    *b = temp;
}

//堆排序维护
void Fixheap(double a[],int n,int i)
{
    int largest = i;
    int lson = i * 2 + 1;
    int rson = i * 2 + 2;
    if (lson<n && a[largest]>a[lson])
    {
        largest = lson;
    }
    if (rson<n && a[largest]>a[rson])
    {
        largest = rson;
    }

    if (largest != i)
    {
        swap(&a[largest], &a[i]);
        Fixheap(a, n, largest);
    }
}

//建堆
void heap_sort(double a[], int n)
{
    int i;
    for (i = n / 2 - 1;i >= 0;i--)
    {
        Fixheap(a, n, i);
    }

}



int main()
{

    for (int i = 0;i < 10000;i++)    //随机生成数据
    {
        Test[i] = rand() % 9999*1.0 + 1;
    }

    int n;
    cout << "请输入要找的第N位最大数";
    cin >> n;
    double* b = new double[n];
    int time1 = 0;
 for (int i = 0;i < 1000;i++)
    {  
        if (time1 < n)
        {
            b[i] = Test[i];
            if (time1 == n - 1)
            {
                heap_sort(b, n);
            }
            time1++;
        }
        else
        {   
            //每次重新堆维护
            Fixheap(b, n,n/2-1);
            if (Test[i] > b[0])
            {
                b[0] = Test[i];
            }
                    
        }
    }
            
 cout<< "第" << n << "位最大值为:";
 cout << b[0];

 /* 方法二
 vector<double> out;  //定义一个vector动态数组
 int time = 0; //用于计数,即先把前n个数存到out数组中

 for (int i = 0;i < 1000;i++)
 {
     if (time < n)
     {
         out.push_back(Test[i]);
         time++;
     }
     else
     {

         //找到当前数组中的最小值,如果接下来Test数组中的数大于这个最小值那么便把它替换掉
         int minnum = min_element(out.begin(), out.end()) - out.begin();
         if (Test[i] > out[minnum])
         {
             out[minnum] = Test[i];
         }

     }
 }

 int minnum = min_element(out.begin(), out.end()) - out.begin();
 cout << "第" << n << "位最大值为:";
 cout << out[minnum] << " ";
 
 
 */

 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值