google笔试

1、假设在n进制下,下面的等式成立,n值是(d)
567*456=150216
a、 9 b、 10 c、 12 d、 18
2、文法G:S->uvSvu|w所识别的语言是:(d)
a、uvw*vu b、(uvwvu)* c、uv(uv)*wvu(vu)* d、(uv)*w(vu)*
3、如下程序段输出是:(c)
char str[][10]={"Hello","Google"};
char *p=str[0];
count<<strlen(p+10);
a、0 b、5 c、6 d、10
 
4、cnt=0
  while(x!=1){
    cnt=cnt+1;
    if(x&1==0)
      x=x/2;
    else
  x=3*x+1;
}
count<<cnt<<end1;
当n=11时,输出:(c)
a、12 b、13 c、14 d、15
 
5、写一段程序判断一个有向图G中节点w是否从节点v可达。(如果G中存在一条从v至w的路径就说节点w是从v可达的)。以下算法是用C++写成的,在bool Reachable函数中,你可以写出自己的算法。
class Graph{
public:
int NumberOfNodes();//返回节点的总数
bool HasEdge(int u,int v);//u,v是节点个数,从零开始依次递增,当有一条从u到v的边时,返回true
};
bool Reachable(Graph&G, int v, int w){
//请写入你的算法
int n = NumberOfNodes();
vector<bool> mark(n,0);
//mark[v] = true;bfs
Queue<int> q;
q.push(v);
while(!q.empty()) {
int t = q.front();
q.pop();
mark[t] = true;
for(int i = 0; i < n; i++) {
if(HasEdge(t,i) && !mark[i]) {
q.push(i);
}
}
}
return mark[w];

//floyd warshell
vector<vector<int> > length(n,n);
fill(length[0],length[n],n+1);
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
length[i][j] = min(length[i][k] + length[k][j], length[i][j]);
if(length[v][w] < n) return true;
return false;
}
 
6、给定一棵所有边的长度均为整数的树,现要求延长其中某些边,使得从根到任意节点的路径长度相等。问满足要求的树的边长度之和最小是多少?请写出你的算法,并分析时间复杂度。






 

题目的量并不大,除了几个单选题,剩下就是三个编程或算法题。单选就不说了,考得比较基础,涉及C语言常识、数据结构、文法、操作系统,主要说说大题。

  大题虽然题型不一,但都有一个重要特点:考递归。精确点说,我每一题都用到了递归。

  第一个的题目(嗯,记的不是很完整):
在一棵(排序?)二叉树中搜索指定值,数据结构定义为(唉唉,数据结构的具体名字都不记得了,my god):
struct Node
{
Node * lnext;
Node * rnext;
int value;
};

函数定义为(情况同上,啥都记不清了):
Node * search(Node * root, int value)
{
}

实现这个search函数。

用递归,经典的树的遍历,pass先。

第二个的题目:
计算Tribonaci队列(嗯,九成九记错了那个单词……),规则是T(n) = T(n - 1) + T(n - 2) + T(n -3),其中T(0) = T(1) = 1,T(2) = 2。
函数定义:
int Tribonaci(int n) {
}

备注,不考虑证整数溢出,尽可能优化算法。

  这一题我一看就知道要考什么,很显然的递归定义,但也是很显然的,这里所谓的优化是指不要重复计算

  简单的说,在计算T(n)的时候要用到T(n - 1)、T(n - 2)和T(n - 3)的结果,在计算T(n - 1)的时候也要用到T(n - 2)和T(n - 3)的结果,所以在各项计算的时候必须把以前计算的结果记录下来,去掉重复计算。这里用到的一点小技巧就是要新写一个函数用来做这种事情,嗯,看看我写的 代码吧!

/**
Get the value of T(n - 1), and retrieve the result of
T(n - 2) and T(n - 3).
@param[in] n The n in T(n).
@param[out] mid Value of T(n - 2).
@param[out] right Value of T(n - 3).
@return Value of T(n - 1).
*/

intfind_trib(intn,int& mid,int& right)
{
if(3 == n)
{
mid = 1;
right = 1;
return2;
}
else
{
inttemp;
mid = find_trib(n - 1, right, temp);
returnmid + right + temp;
}
}

/**
Find value of T(n).
@param[in] The n in T(n).
@return Value of T(n).
@note T(n) = T(n - 1) + T(n - 2) + T(n - 3) (n > 2)
T(0) = T(1) = 1, T(2) = 2.
*/

inttribonaci(intn)
{
if(n < 0)
{
// Undefined feature.
return0;
}

if(0 == n || 1 == n)
{
return1;
}

if(2 == n)
{
return2;
}

intmid, right;
intleft = find_trib(n, mid, right);
returnleft + mid + right;
}

  啊啊,对了,答卷的时候我可没心情写注释……刚才到VC.Net 2003上测试了一下,貌似没有啥问题。唉,看来我多少还是懂一点算法的……

  第三个的题目:
  在一个无向图中,寻找是否有一条距离为K的路径,描述算法即可,不用实现,分析算法的时间和空间复杂度,尽量优化算法。

  OK,这个就是传说中的软肋了………………我也就不把自己的答案写出来了(丢人啊),虽然后来仔细想想,我那个挫挫的方法也能够用……只是效率……

  That's all.

算法+数据结构+操作系统+编译原理+网络+离散数学

1、 两个二进制数的异或结果

2、 递归函数最终会结束,那么这个函数一定(不定项选择):

  1. 使用了局部变量
  2. 有一个分支不调用自身
  3. 使用了全局变量或者使用了一个或多个参数

3、以下函数的结果?
int cal(int x)
{
    if(x==0)
return 0;
    else
      return x+cal(x-1);
}

4、 以下程序的结果?

void foo(int*a, int* b)
{
    *a = *a+*b;
    *b = *a-*b;
    *a = *a-*b;
}
void main()
{
    int a=1, b=2, c=3;
    foo(&a,&b);
    foo(&b,&c);
    foo(&c,&a);
    printf("%d, %d, %d", a,b,c);
}

5、下面哪项不是链表优于数组的特点?

  1. 方便删除 2. 方便插入 3. 长度可变 4. 存储空间小

6、T(n) = 25T(n/5)+n^2的时间复杂度?

7、n个顶点,m条边的全连通图,至少去掉几条边才能构成一棵树?

8、正则表达式(01|10|1001|0110)*与下列哪个表达式一样?

  1.(0|1)* 2.(01|01)* 3.(01|10)* 4.(11|01)* 5.(01|1)*

9、如何减少换页错误?

  1. 进程倾向于占用CPU
  2. 访问局部性(locality of reference)满足进程要求
  3. 进程倾向于占用I/O
  4.使用基于最短剩余时间(shortest remaining time)的调度机制
  5. 减少页大小

10、实现两个N*N矩阵的乘法,矩阵由一维数组表示

11、找到单向链表中间那个元素,如果有两个则取前面一个

12、长度为n的整数数组,找出其中任意(n-1)个乘积最大的那一组,只能用乘法,不可 以用除法。要求对算法的时间复杂度和空间复杂度作出分析,不要求写程序。

三道大题第一个还蛮简单,是向双向列表插入一个节点,第二个问题比较恶心,判断A字符串中的各个字符数目是否不大于B字符串中的各个字符数目,由于没时间 了就没写完,第三题更是相当及其以及特别的恶心,找到整数数组中满足A*B=C的元素,而且要更优的,算了半天的时间复杂度还是没写出来。

1、有两根不均匀分布的香,香烧完的时间是一个小时,你能用什么方法来确定一段15分钟的时间?

答:2根香同时点燃,第一根两头都点燃,第二根只点一头, 第一根点完的时候是半个小时,接着把第二根两头都点燃,第二根点完的时候就是15分钟。


2、一个经理有三个女儿,三个女儿的年龄加起来等于13,三个女儿的年龄乘起来等于经理自己的年龄,有一个下属已知道经理的年龄,但仍不能确定经理三个女 儿的年龄,这时经理说只有一个女儿的头发是黑的,然后这个下属就知道了经理三个女儿的年龄。请问三个女儿的年龄分别是多少?为什么?


答:2,2,9, 1岁不可能


3、有三个人去住旅馆,住三间房,每一间房$10元,于是他们一共付给老板$30,第二天,老板觉得三间房只需要$25元就够了于是叫小弟退回$5给三位 客人,谁知小弟贪心,只退回每人$1,自己偷偷拿了$2,这样一来便等于那三位客人每人各花了九元,于是三个人一共花了$27,再加上小弟独吞了不$2, 总共是$29。可是当初他们三个人一共付出$30那么还有$1呢?

答:没错,三个人付了27块,老板拿了25块,小弟拿了2块

4、有两位盲人,他们都各自买了两对黑袜和两对白袜,八对袜了的布质、大小完全相同,而每对袜了都有一张商标纸连着。两位盲人不小心将八对袜了混在一起。 他们每人怎样才能取回黑袜和白袜各两对呢?


答:不知道,还要仔细想想

5、有一辆火车以每小时15公里的速度离开洛杉矶直奔纽约,另一辆火车以每小时20公里的速度从纽约开往洛杉矶。如果有一只鸟,以30公里 每小时的速度和两辆火车同时启动,从洛杉矶出发,碰到另一辆车后返回,依次在两辆火车来回飞行,直到两辆火车相遇,请问,这只小鸟飞行了多长距离?


答:记好两车相遇时间,就是鸟飞行时间,乘以其飞行速度就得到飞行距离。


6、你有两个罐子,50个红色弹球,50个蓝色弹球,随机选出一个罐子,随机选取出一个弹球放入罐子,怎么给红色弹球最大的选中机会?在你的计划中,得到红球的准确几率是多少?


答:不知道,还要仔细想想


7、你有四个装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的重量+1.只称量一次,如何判断哪个罐子的药被污染了?

答:不知道,还要仔细想想

8、你有一桶果冻,其中有黄色,绿色,红色三种,闭上眼睛,抓取两个同种颜色的果冻。抓取多少个就可以确定你肯定有两个同一颜色的果冻?

答:4


9、对一批编号为1~100,全部开关朝上(开)的灯进行以下*作:凡是1的倍数反方向拨一次开关;2的倍数反方向又拨一次开关;3的倍数反方向又拨一次开关……问:最后为关熄状态的灯的编号。


答:不知道,还要仔细想想


10、想象你在镜子前,请问,为什么镜子中的影像可以颠倒左右,却不能颠倒上下?


答:人的眼睛是左右对称的

11、一群人开舞会,每人头上都戴着一顶帽子。帽子只有黑白两种,黑的至少有一顶。每个人都能看到其它人帽子的颜色,却看不到自己的。主持 人先让大家看看别人头上戴的是什幺帽子,然后关灯,如果有人认为自己戴的是黑帽子,就打自己一个耳光。第一次关灯,没有声音。于是再开灯,大家再看一遍, 关灯时仍然鸦雀无声。一直到第三次关灯,才有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子?

一、单选

1、80x86中,十进制数-3用16位二进制数表示为?

2、假定符号-、*、$分别代表减法、乘法和指数运算,且

1)三个运算符优先级顺序是:-最高,*其次,$最低;

2)运算符运算时为左结合。请计算3-2*4$1*2$3的值:

(A)4096,(B)-61,(C)64,(D)-80,(E)512

3、下列伪代码中,参数是引用传递,结果是?

calc(double p, double q, double r){q=q-1.0;r=r+p}
main(){
  double a = 2.5, b = 9.0;
  calc(b-a, a, a);
  print(a);
}
(A)1.5 (B)2.5 (C)10.5 (D)8 (E)6.5

4、求输出结果:

int foo(int x, int y){
  if(x <=0 || y <= 0) return 1;
  return 3 * foo(x - 1, y / 2);
}
printf("%d\n", foo(3, 5));
(A)81 (B)27 (C)9 (D)3 (E)1

5、下列哪个数据结构在优先队列中被最广泛使用?

(A)堆 (B)数组 (C)双向链表 (D)图 (E)向量

6、以下算法描述了一个在n国元素的双向链表中找到第k个元素的 方法(k >= 1且k <= n):

如果k <= n - k,从链表开始往前进k-1个元素。

否则,从终点出发,往回走n - k个元素。

这个算法的时间代价是?

(A)θ(nlogn) (B)θ(max{k, n - k}) (C)θ(k + (n - k))

(D)θ(max{k, k - n}) (E)θ(min{k, n - k})

7、有一个由10个顶点组成的图,每个顶点有6个度,那么这个图有几条边?

(A)60 (B)30 (C)20 (D)80 (E)90

8、正则表达式L = x*(x|yx+)。下列哪个字符串不符合L

(A)x (B)xyxyx (C)xyx (D)yxx (E)yx

9、为读取一块数据而准备磁盘驱动器的总时间包括

(A)等待时间 (B)寻道时间 (C)传输时间 (D)等待时间加寻道时间

(E)等待时间加寻道时间加传输时间

二、算法

1、打印出一个二叉树的内容。

2、在一个字符串中找到第一个只出现一次的字符。如abaccdeff,输出b。

3、给定一个长度为N的整数数组(元素有正有负),求所有元素之和,最大的一个子数组。分析算法时空复杂度。不必写代码。


附上动态规划做法的答案:

最大子序列

问题:

给定一整数序列A1, A2,... An (可能有负数),求A1~An的一个子序列Ai~Aj,使得Ai到Aj的和最大

例如: 整数序列-2, 11, -4, 13, -5, 2, -5, -3, 12, -9的最大子序列的和为21。 对于这个问题,最简单也是最容易想到的那就是穷举所有子序列的方法。利用三重循环,依次求出所有子序列的和然后取最大的那个。当然算法复杂度会达到O (n^3)。显然这种方法不是最优的,下面给出一个算法复杂度为O(n)的线性算法实现,算法的来源于Programming Pearls一书。 在给出线性算法之前,先来看一个对穷举算法进行优化的算法,它的算法复杂度为O(n^2)。其实这个算法只是对对穷举算法稍微做了一些修改:其实子序列的 和我们并不需要每次都重新计算一遍。假设Sum(i, j)是A[i] ... A[j]的和,那么Sum(i, j+1) = Sum(i, j) + A[j+1]。利用这一个递推,我们就可以得到下面这个算法:

int max_sub(int a[],int size)
{
  int i,j,v,max=a[0];
  for(i=0;i<size;i++)
  {
    v=0;
    for(j=i;j<size;j++)
    {
      v=v+a[j];//Sum(i, j+1) = Sum(i, j) + A[j+1]
        if(v>max)
         max=v;
    }
  }
  return max;
}

那怎样才能达到线性复杂度呢?这里运用动态规划的思想。先看一下源代码实现:
int max_sub2(int a[], int size)
{
  int i,max=0,temp_sum=0;
  for(i=0;i<size;i++)
  {
      temp_sum+=a[i];
      if(temp_sum>max)
        max=temp_sum;
      else if(temp_sum<0)
        temp_sum=0;
  }
  return max;
}

在这一遍扫描数组当中,从左到右记录当前子序列的和temp_sum,若这个和不断增加,那么最大子序列的和max也不断增加(不断更新 max)。如果往前扫描中遇到负数,那么当前子序列的和将会减小。此时temp_sum 将会小于max,当然max也就不更新。如果temp_sum降到0时,说明前面已经扫描的那一段就可以抛弃了,这时将temp_sum置为0。然后, temp_sum将从后面开始将这个子段进行分析,若有比当前max大的子段,继续更新max。这样一趟扫描结果也就出来了。


9个选择题,2个编程,1个算法.选择题,感觉比较基础,不知里面有没有设地雷?反正没啥印象了.

  编程1,打印二叉树,实现语言不限,先后也不限.

  编程2,给定一个字符串数组,从中找出第一个只出现一次的字母.

  算法题,给定一个整数数组,从中切出一个连续片段,保证其元素和最大.求最优算法,分析时间和空间复杂度.

一些Google笔试题目

一、选择题
1.在n进制中, 567*456=150216 ,则n是多少
A.9 B.10 C.12 D.18
2.输出是什么
String str[][10]={"Hello","Google"};
char* p=str[0];
cout<<strlen(p+10)<<endl;
3.输出是什么
int x=11;
int t=0;
while(x!=1){
t=t+1;
if(x&1==0)
x=x/2;
else
x=x*3+1;
}
cout<<t<<endl;
4.图的广度遍历需要什么数据结构
堆/ 栈/ 队列/ ...
5.二叉树前序ABCDEF,中序CBAEDF,后序是什么?
6.f(n)函数的复杂度是什么
f(n)
{
if(n==0) return 1;
return n*f(n-1)+1;
}
A. O(n) B. O(n^2) C. O(n^3) D. O(n^4)
7.下列哪个进程的状态转换是不可能发生的
A. 运行->等待 B. 等待->运行 C. 运行->就绪 D. 等待->就绪
8.系统中6个进程,7个同类资源, 进程一次只能申请一个资源, 最多可以申请2个资源,那么系统:
A. 一定不死锁 B. 一定死锁 C. 不一定死锁 D. 任何时刻始终有一个进程不能拥有资源.
9.文法S->uvSvu|w,则它能识别的语言:
A. uvw*vu B. (uvwvu)* C. uv(uv)*wvu(vu)* D. (uv)*w(vu)*
10.一个文件由3块组成,每块有2份拷贝,任何一块坏的概率是10%,问文件被破坏的
概率最接近下面多少
A. 0.5% B. 1% C. 2.5% D. 4% E. 3.3% F. 5%
二、算法题
1. 有向图G, 写函数判断顶点v和w是否可达.
Graph G{
int TotalVertexNum(); //顶点总数
bool HasEdge(int u, int v)//顶点u,v是否有边,顶点序号由0开始
}
2. 一棵树,各边的长度均为整数, 确定一个算法延长各边的长度(即只能增加,不能减少),使得各点到根的距离一样,且所有边的长度和最小. 写算法思路和步骤,不用写详细过程, 最后要分析事件复杂度.




1.单项选择题
1. 下面一段代码的输出是[ ]
void fn( int* b){
(*b)++;
}
int main(){
int a=7;
fn(&a);
cout<<a;
return 0;
}
A.0 B.7 C.8 D.undefined

2. 定义int i,j,*p=&i; 那么下面哪条语句可以完成i=j的赋值[ ]
A.i=*p; B. *p=*&j; C.i=&j; D.I=**p;

3. 用二叉搜索树和哈希表存储相同的数据集,对于以下何种操作,二叉搜索树比哈希表
速度更快?[ ]
A.检索 B. 插入 C.删除 D.更新 E.排序

4. 包含N个几点和M条边的有向带权图G, 边的权为正, 以下操作中不可以在O(N+M)
的时间复杂度内完成的操作是:[ ]
A. 求结点s到结点t之间的最短距离
B. 求距离结点s最近的结点
C. 已知起始结点, 对图G中的结点进行拓扑排序
D. 求图G的最大强连通子图

5. 有如下递归函数f(n),其时间复杂度为[ ]
int f(int n){
if(n==0)
return 0;
if(n==1)
return 1;
return ( 5*f(n-1) - 6*f(n-2));
}
A.O(n) B. O(n^2) C. O(n^3) D. O(2^n)

6. 下面所述步骤中,哪一个不是创建经常所必需有的[ ]
A.由调度程序为进程分配CPU B.建立一个进程控制块
C.为进程分配内存 D.将进程控制块链入就绪队列

7. 在多进程的系统中,为了保证公区变量的完整性,各进程应互斥进入临界区。所谓临
界区是[ ]
A.一个缓冲区 B.一个数据区 C.一个同步机构 D.一段程序

8. 能产生满足如下条件语言的正则表达式是:1.每一个a后至少紧跟两个c; 2.每一个b
后至少紧跟一个c [ ]
A.(acc|bc|c)* B.(acc|bc)* C.(ac|bc)* D.不是正则语言

9. 以下哪项不是RPC(远程过程调用)的特点[ ]
A.速度快 B.降低系统耦合度 C.可以实现异构系统间的协作

10. 有三个桶,容量分别是3升,5升,7升,你只能进行下面的操作:
把一个桶中所有的水倒掉;
把一个桶A中的水倒入桶B,直到桶A空了或者桶B满了;
假设一开始容量为3升和5升的桶是满的,7升的桶是空的,希望通过一系列操作使3个桶
中任意一个中正好有4升水,那么至少需要[ ]次操作。
A.3 B.5 C.7 D.不可能

2. 程序设计与算法
2.1 实现如下编码算法,对于重复2-9次数的字符,用两个数字表示,即NX(其中N为重
复的次数,X为重复的字符,下同),超过九个则先输出9X,然后处理剩下的字符。对于
连续的不重复的字符,则两边加1来封字符串。如果被封的字符串其中有数字为1,则用1
来转义。 示例: AAAAAABCCCC -> 6A1B14C, 12344 -> 11123124。。。(下面的框
架是用C++语言写的。你可以用你熟悉的语言。)
void encode (const char* text, char* dest)
text 为需要编码的字符串,dest表示编码输出的目标空间,而空间足够大

2.2给定一颗有n个结点的二叉树。求它的所有结点数为m的连通子图数目。m<=n分析你的
算法的时间复杂度,解释算法即可,不必写代码。

猜你喜欢

转载自vergilwang.iteye.com/blog/2011209