谷歌面试题目
1. 求两个数或N个数的最小公倍数和最大公约数
int gcd(int a,int b) { if(a<b) swap(a,b) while(b>0) { int r = a%b; a = b; b = r; } return a; } // 最大公约数,最小公倍数 = a*b/gcd(a,b)
2. 输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc
假设在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。
针对第一个字符,两种选择:
一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;
二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符;
这两种选择都很容易用递归实现,其实是和输入两个整数n和m,从数列1,2,3...n中随意取几个数,使其和等于m,要求列出所有的组合类似的,对于数字i,两种选择,一种是放入到组合中,在剩余的n-1个数中选择数=sum-i,一种是不放入,在剩余的n-1个数中选择数=sum,同样可以用递归实现。
void Combination(char *string) { assert(string != NULL); vector<char> result; int i , length = strlen(string); for(i = 1 ; i <= length ; ++i) Combination(string , i ,result); } void Combination(char *string ,int number , vector<char> &result) { assert(string != NULL); if(number == 0) { static int num = 1; printf("第%d个组合\t",num++); vector<char>::iterator iter = result.begin(); for( ; iter != result.end() ; ++iter) printf("%c",*iter); printf("\n"); return ; } if(*string == '\0') return ; result.push_back(*string); Combination(string + 1 , number - 1 , result); result.pop_back(); Combination(string + 1 , number , result); }
3. 有1000桶酒,其中1桶有毒。而一旦吃了,毒性会在1周后发作。现在我们用小老鼠做实验,要在1周后找出那桶毒酒,问最少需要多少老鼠。
解法一:二进制表示法
1000桶酒编号1-1000的二进制表示法所需要的最大位数为10. (2的10次方为1024)
桶1-1000的二进制表示为:
1 00 0000 0001
2 00 0000 0010
... ...
100 11 1110 1000
老鼠编号1-10可理解为二进制表示中位的概念。如鼠1表示第一位为1,鼠10表示第10位为1.(从右至左)
鼠1-10的二进制表示为:
1 00 0000 0001 1
2 00 0000 0010 2
... ...
10 10 0000 0000 512
鼠1-10分别喝桶1-1000中与鼠编号相同位为1的酒。 如鼠1喝所有奇数桶,因为奇数桶的第一位都为1。 1-1000的可由任何一个老鼠的编号组成,如酒12,则由3号鼠和4号鼠去喝该桶酒。
最后统计死鼠的编号。 如鼠3,鼠4,鼠5 死亡,表明桶56(00 0001 1100)有毒。
解法二:矩阵表示法
1000桶酒可摆成33*33的矩阵。编号分别为
(1,1) ,(1,2) ,...... (1,33)
(2,1) ,(2,2) ,...... (2,10)
..... ...... ...... ......
(33,1) ,(33,2) ,...... (33,33)
安排66只鼠喝酒,第一组33只老鼠排成纵列横向喝酒,另一组33只老鼠排成横列纵向喝酒。
若有2中鼠死亡,便可锁定是哪一桶酒有毒。如没有鼠死亡,便表明剩下的一桶有毒。
解法一解法二比较:
解法一所需老鼠较少,但是死亡率比较高,而且每只老鼠喝的酒不均匀,差异大。
解法二所需老鼠较多,但是死亡率比较低,最多2只。并且每只老鼠喝的酒量相同。
5. 用最简单, 最快速的方法计算出下面这个圆形是否和正方形相交。
3D坐标系 原点(0.0,0.0,0.0)
圆形:
半径r = 3.0
圆心o = (*.*, 0.0, *.*)
正方形:
4个角坐标
1:(*.*, 0.0, *.*)
2:(*.*, 0.0, *.*)
3:(*.*, 0.0, *.*)
4:(*.*, 0.0, *.*)
假设圆心为O,正方形四个顶点是ABCD,分别计算OA,OB,OC,OD
min_d = min(OA,OB,OC,OD)
max_d = max(OA,OB,OC,OD)
如果 max_d < r ,则在圆内,不相交
如果 min_d <= r <= max_d ,则相交
如果 max_d > r, 则计算O到四条边的距离并取最小的即为minEdgeDistance,如果minEdgeDistance<=r,则相交