您的位置:首页 > 职场人生

面试跟序列有关的问题汇总

2013-10-05 20:13 267 查看
  面试中比较多会出序列有关的面试题,所以就总结下

(1)一个长度N为的序列,求前K小的数

  1.排序 N*log(N)

  2.最大堆N*log(K)

  3.有平均时间复杂度O(n)的算法,因为我们可以在O(n)的时间内找到未排序数组里面第k小的数的值,然后再遍历一下数组,把值小于等于第k小的全都输出(感谢 huangnima)

(2)有两个长度为N的有序序列A和B,在A和B中各任取一个数可以得到N^2个和,求这N^2个和中最小的N个。

  1.比较直观的想法是将A与B的数字相加后排序,时间复杂度O(N*N*log(N*N))

  2.考虑到要求的是求最小的N个数字,所以从这里考虑优化,维护一个大小为N的最小堆 log(N),对于N^N个数字的选择有没有优化方法,有!

     可以把这些和看成n个有序表:

    – A[1]+B[1] <= A[1]+B[2] <= A[1]+B[3] <=…

    – A[2]+B[1] <= A[2]+B[2] <= A[2]+B[3] <=…

    –…

    – A
+B[1] <= A
+B[2] <= A
+B[3] <=…

    当然并不用计算所有的和

    综上所述,可以采用K路归并:

    就是最小堆的元素增加一个状态量(下标),记录当前列最小值所在位置,下次遍历时从这里开始!

    总的时间复杂度O(N*log(N))

#include<stdio.h>

int A[100099],d[100099][20];
int n,m;

int min(int a,int b){
return a<=b?a:b;
}

void RMQ_init(){
int i,j;
for(i=1;i<=n;i++)d[i][0]=A[i];
for(j=1;(1<<j)<=n;j++){
for(i=1;i+(1<<j)-1<=n;i++){
d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}
}
}

int RMQ_find(int ll,int rr){
int k=0;
while((1<<(k+1))<=(rr-ll+1))k++;
return min(d[ll][k],d[rr-(1<<k)+1][k]);
}

int main(){
while(scanf("%d",&n)!=EOF){
int i,j;
for(i=1;i<=n;i++){
scanf("%d",&A[i]);
}RMQ_init();
scanf("%d",&m);
int ll,rr;
while(m--){
scanf("%d%d",&ll,&rr);
printf("%d\n",RMQ_find(ll,rr));
}
}

return 0;
}


View Code
  2.线段树 O(n*logn)

如果有相关的题目,会继续更新
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: