阿里巴巴笔试题摘录

6.在c++程序中,如果一个整型变量频繁使用,最好将他定义为()

A.auto

B.extern

C.static

D.register

思路:寄存器快嘛,而且整型也正好能放进寄存器,详见变量的存储类型

7.长为n的字符串中匹配长度为m的子串的复杂度为()

A.O(N)

B.O(M+N)

C.O(N+logM)

D.O(M+logN)

思路:KMP算法的时间复杂度是O(M+N),但是BM算法会相对而言更快,但是也是O(M+N)。
当时选的是B,但是加个“最”总让人不放心,回来查看资料,用后缀数组的方法可以在O(M+LOGN)时间内完成,
但是这没有包含后缀数组预处理所需的时间(一般为NLOGN)。(ps:以后如果不确定还是跟着直觉走吧


8.判断一包含n个整数a[]中是否存在i、j、k满足a[i] + a[j] = a[k]的最小的时间复杂度为()

A. O(n3)     B.O(n2lgn)    C.O(n2)   D.O(nlgn)

思路:O(N2)的算法能想一大堆,虽然最终我选的C,比如说用hash的话,三维遍历可以轻松编程二维遍历,但是总感觉是不是应该有nlgn的算法。

皇冠用户仓库开销:某淘宝金冠用户在多个城市有仓库,每个仓库的储货量不同,现在要通过货物运输,将每次仓库的储货量变成一致的,n个仓库之间的运输线路围城一个圈,运输只能在相邻的仓库之间进行,设计最小的运送成本(运货量*路程)

image

思路:这个在各种online-judge平台上都有答案,纯粹的数学问题,

如图,这是一个仓库分布的模拟,假设从第i个仓库向第i+1个仓库转移的物品为Pi个单位,其中Pi为负表示思是从i+1个仓库转移到第i个仓库,第n个仓库转移到第一个仓库即为Pn,设最后每个仓库平均后的货物为ave个单位,则有要最小化|P1|+|P2|+…+|Pi|+…+|Pn|

                               ave[i]=ave=A[i]-Pi+Pi-1

                               ave[1]=A[1]-P1+Pn

                       然后设W[i]=ave[i]-A[i]=-Pi+Pi-1

                       于是S[i]=W[1]+W[2]+….W[i]=Pn-Pi

                   即Pi=Pn-S[i] ,所以问题归结到最小化|Pn-S[1]|+|Pn-S[2]|+…+|Pn-S[n]|

                 所以Pn是S中位数的时候最小

 

#include<queue>
#include<string>
#include<pthread.h>
#include<algorithm>
#include<numeric>
using namespace std;
int s[10005];
int s2[10005];
int p[10005];
void findMinCost(int* arr,size_t n){
    //nth_element(arr+1,arr+1+n/2,arr+1+n);
    int sum=accumulate(arr+1,arr+1+n,0);
    int ave=sum/n;
    s[1]=ave-arr[1];
    for(int i=2;i<n;++i){
      s[i]=s[i-1]+ave-arr[i];
    }
    copy(s,s+n+1,s2);
    nth_element(s2+1,s2+1+n/2,s2+n+1);
    
    p[n]=s2[n/2+1];
    for(int i=1;i<=n;++i){
     p[i]=p[n]-s[i];
   }
   for(int i=1;i<=n;++i){
     cout<<p[i]<<" " ;
   }
   cout<<endl;

}
int main(){
  int arr[]={0,5,4,3,2,1};
  
  
  findMinCost(arr,sizeof(arr)/sizeof(int)-1);
  return 0;
}

第20题:字符串数组seq[] = a,b,c,d,aa,ba,ca,da,ab,bb,cb,db,ac...,aaa,aba,...
(1)aaa是第几个字符串

(2)ababacd是第几个
(3)第1000个字符串是什么
(4)编写函数find(),返回字符串在seq中是第几个(语言不限)


分析:
(1).长度,很容易推导出长度是n的字符串在第4^(n-1)个之后,aaa是1位和2位全排列后的第一个,即第4^(3-1)+4^(2-1)之后的第一个,也即第21个
(2)字符,每个字符可以判断出它之前的字符全排列了多少次,
字    符: a b a b a c d
全排列: 0 1 0 1 0 2 3
4^次幂: 0 1 2 3 4 5 6
即1*4^1+1*4^3+2*4^5+3*4^6 = 14405(考场不让用计算器...换成2的次幂来算)
(3)把1000转为二进制是 11 11 10 10 00
他们分别对应4进制里的 3    3   2   2   0
对应字符就是 d d c c a,倒序就是accdd,这里算出来的是1001的字符串
第1000个是上一个, 即 accdd-1 = dbcdd
(4)可执行代码如下:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;

  4. long find(char seq[]){
  5.         long sum=1;
  6.         long tmp=1;
  7.         int len = strlen(seq);
  8.         for (int i=0;i<len;i++)
  9.         {
  10.                 sum+=(seq[i]-'a')*tmp;
  11.                 tmp*=4;
  12.         }
  13.         return sum;
  14. }

  15. int main(){
  16.         cout<<find("ababacd")<<endl;
  17.         cout<<find("dbcdd")<<endl;
  18.         return 0;
  19. }
复制代码

 


战报交流:战场上不同的位置有N个战士(n>4),每个战士知道当前的一些战况,现在需要这n个战士通过通话交流,互相传达自己知道的战况信息,每次通话,可以让通话的双方知道对方的所有情报,设计算法,使用最少的通话次数,是的战场上的n个士兵知道所有的战况信息,不需要写程序代码,得出最少的通话次数。

点击打开链接


有N个人,其中一个明星和n-1个群众,群众都认识明星,明星不认识任何群众,群众和群众之间的认识关系不知道,现在如果你是机器人R2T2,你每次问一个人是否认识另外一个人的代价为O(1),试设计一种算法找出明星,并给出时间复杂度(没有复杂度不得分)。答案:
遍历 1~n 这n个人;
首先取出 1号 和 2号,
如果 1 认识 2, 那么把 1 去掉;
如果1不认识2,就可以把2去掉了。
每次比较都去掉一个,如此循环;n-1次之后只有一个人了
时间复杂度: O(n-1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值