有的时候想想懒得每次遇到类似问题就重新编代码,所以主要是为了保存代码,就重新记录一些简单题的解法。
问题:
给定一个无序系列包含有n个数,求其前m大数
算法:
1. 对该系列进行排序,然后取前m大的数。算法时间复杂度为O(nlogn)
2. 如果m比较小,对系列流有序保存前m大数,时间复杂度为O(mn)
3. 维持一个m个元素的最小堆,该堆保存的是前m大数,新添加的数只要跟该堆中最小数比较,若大则替换并调整堆,否则舍弃,时间复杂度为O(nlogm)
下面是一个简单练习题的三种算法C++代码:
题目(http://acm.hdu.edu.cn/showproblem.php?pid=3785)
//------------------------------------------------//--------------------解法1-----------------------
//------------------------------------------------
#include<iostream>
#include <algorithm>
using namespace std;
int main()
{
int a,b[100001],m,n,i,j;
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
for(i=0;i<n;i++)
scanf("%d",&b[i]);
sort(b,b+n);
for(i=0,j=n-1;i<(m>n?n:m);i++,j--)
{
if(i!=0)
printf(" ");
printf("%d",b[j]);
}
printf("\n");
}
return 0;
}
//------------------------------------------------
//--------------------解法2-----------------------
//------------------------------------------------
#include<stdio.h>
#define MAX 999999999
int main()
{
int a,b[20],m,n,i,j;
while(scanf("%d%d",&n,&m))
{
for(i=1;i<=15;i++)
b[i]=-MAX;
if(n==0&&m==0)break;
for(i=1;i<=n;i++)
{
scanf("%d",&a);
if(a<=b[m])continue; //新的数如果比已有的m大的数小,就不用考虑了
for(j=m-1;j>=1;j--) //否则比第j个数大,则第j大后移到j+1大
if(b[j]<a)b[j+1]=b[j];
else break; //最后找出比a大的数为第j大,退出
b[j+1]=a; //因为a比第j大的数小,比j+1大,所以j+1后面的全部后移,然后a插入到第j+1个数中
}
for(i=1;i<=(m>n?n:m);i++)
{
if(i!=1)
printf(" ");
printf("%d",b[i]);
}
printf("\n");
}
return 0;
}
//------------------------------------------------
//--------------------解法3-----------------------
//------------------------------------------------
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a,m,n,i,j,b[12];
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
int nn = (m>n)?n:m;
for(i=1;i<=nn;i++)
{
scanf("%d",&b[i]);
j = i;
while(j/2>=1&&b[j]<b[j/2])
{
int t = b[j];
b[j] = b[j/2];
b[j/2] = t;
j /= 2;
}
}
for(;i<=n;i++)
{
scanf("%d",&a);
if(a<=b[1])continue;
b[1] = a;
j = 1;
while(j*2<=m)
{
int x = j*2;
if(x+1<=m&&b[x+1]<b[x])
x=x+1;
if(b[x]<b[j]){
int t = b[j];
b[j] = b[x];
b[x] = t;
j = x;
}
else break;
}
}
sort(b+1,b+nn+1);
for(i=nn;i>0;i--)
{
if(i!=nn)
printf(" ");
printf("%d",b[i]);
}
printf("\n");
}
return 0;
}