1亿个数字找最大的10000个

解决思路:

将1亿个数字的前10000个(0~9999)进行排序(由大到小),获得res[]minIdx = zoneBeginIdx= 9999(zoneBeginIdx:可能发生替换的区域的最前面的一个) ;
后面(10000 ~ 1亿-1)遍历,每次都与res最后一个(即最小的作比较),
如果比res[minIdx]大,则res[minIdx] = res[当前],替换完后我们要保证最小的数字在 可能发生替换的区域 内,但此时该数字可能比res[9998]甚至res[0…9997]大,所以我们要判断是否让zoneBeginIdx往前扩一个:--zoneBeginIdx

可以发现:只要我们能确认区域界线右边的第一个数字 与 区域边界左边的第一个数字大小关系 即可,最方便的方法就是当插入的数字在区域边界右边第一个位置时,扩展区域,这样两边的关系一定可以确认,扩展完后再找到最小的数字idx,便于下次替换;

继续往后遍历。

template< class T, class I >
void solution_4( T BigArr[], T ResArr[] )
{
       //取最前面的一万个
       memcpy( ResArr, BigArr, sizeof(T) * RES_ARR_SIZE );
       //排序
       std::sort( ResArr, ResArr + RES_ARR_SIZE, std::greater_equal() );
       //最小元素索引
       unsigned int MinElemIdx = RES_ARR_SIZE - 1;
       //可能产生交换的区域的最小索引
       unsigned int ZoneBeginIdx = MinElemIdx;
       //遍历后续的元素
       for( unsigned int i = RES_ARR_SIZE; i < BIG_ARR_SIZE; ++i )
       {    
              //这个后续元素比ResArr中最小的元素大,则替换。
              if( BigArr[i] > ResArr[MinElemIdx] )
              {
                     // 1.替换最小的
                     ResArr[MinElemIdx] = BigArr[i];
                     // 2.重新定边界
                     // 	交换的数字可能比区域边界前的数字还大,需要将边界左边最小的数字拿来一起比
                     if( MinElemIdx == ZoneBeginIdx )
                            --ZoneBeginIdx;
                     //3.查找定边界后的最小元素
                     unsigned int idx = ZoneBeginIdx;
                     unsigned int j = idx + 1;
                     for( ; j < RES_ARR_SIZE; ++j )
                     {
                            if( ResArr[idx] > ResArr[j] )
                                   idx = j;
                     }
                     MinElemIdx = idx;
              }
       }
}

参考文章


欢迎大家评论哟!如果本文对您有帮助,请点个赞,您的点赞对我很重要!这次一定!感谢!!!
转发请注明出处呦!感谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Letian

您的打赏是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值