google的几道面试题
Question1:如何判断两个矩形是否有重叠区域?
Answer(java):
public boolean checkCross(Rectangle m, Rectangle n) { //求出m,n矩形的重心 Point m_core = new Point(m.getLeft().getX() + m.getLength()/ 2, m.getLeft().getY() + m.getWidth()/ 2); Point n_core = new Point(n.getLeft().getX() + n.getLength()/ 2, n.getLeft().getY() + n.getWidth()/ 2); return Math.abs(m_core.getX() - n_core.getX()) < (m.getLength()/ 2 + n.getLength()/ 2) && Math.abs(m_core.getY()-n_core.getY()) < (m.getLength()/ 2 + n.getWidth()/ 2); }
原理如下图所示:
Question2: 给出一个函数,对一个数组进行随机排列,每种排列出现的概率是n!分之一
Answer(java):
public int[] rank(int[] m ,int length){ public int[] rank(int[] m ,int length){ int[] n=m.clone(); int place;//表示将放于i位置的数的位置 int temp; for(int i=0;i<length-1;i++){ //产生【i,length-1】的随机数 place=i+(int)(Math.random()*(length-i)); temp=n[place]; n[place]=n[i]; n[i]=temp; } return n; }
Question3:( 约瑟夫环问题)n个人(编号为0~n-1),从0开始报数,报到(m-1)的人退出,剩下的人继续从0开始报数。求最后留下的人的编号。
Answer(java):
1、用循环链表来模拟整个过程
2、令f[n]表示n个人时最后留下的人的编号
递推公式如下:
n=1时,f[1]=0;
n>1时,f[n]=(f[n-1]+m)%n
原理如下图所示:
Question4:(1)给一个字符串,要你统计里面的ASCII码的频数,其中大写的字母算作小写字母来统计,输出的时候这样输出:假如字符串是bbCca* ,则输出b:2 C:2 a:1 *:1,按字母首次出现的顺序输出。给出一个c函数的形式为void calc(char* input,int len),你也可以用你喜欢的语言去写。(2)给出测试数据来证明程序运行的各种可能性。
Answer(java):
public void calc(String input,int length){
//出现的次数统计数组
int[] ascii_times=new int[128];
for(int i=0;i<ascii_times.length;i++){
ascii_times[i]=0;
} int lowercase_start=(int)'a';
int lowercase_end=(int)'z';
int gap=(int)'a'-(int)'A'; //是否与之前的字符发生重复数组
boolean[] flag=new boolean[length];
for(int i=0;i<length;i++){
flag[i]=false;
} //对input数组进行扫描
for(int i=0;i<length;i++){ int ascii=(int)input.charAt(i);
if(ascii>=lowercase_start && ascii<=lowercase_end){
ascii-=gap;
}
if(ascii_times[ascii]>0){
flag[i]=true;
}
ascii_times[ascii]++;
}
//输出
for(int i=0;i<length;i++){ int ascii=(int)input.charAt(i);
if(ascii>=lowercase_start && ascii<=lowercase_end){
ascii-=gap;
}
if(flag[i]==false){
System.out.println(input.charAt(i)+":"+ascii_times[ascii]+" ");
}
}
}
Question5:给定一个数组A,里面只出现0-9这10个数字,但不一定全部出现,然后给定一个K的值,求利用A中数字(不一定全用)构成大于K的最小整数。例如A={0,1}, k =12,则结果为100。
Answer(java):
public int getMinAns(int K,String nums){ int temp_K=K;
//获取K的位数到K_digits
int K_digits=0;
do{
temp_K=temp_K/10;
K_digits++;
}while(temp_K>0);//此处只能用do-while,因为K可能为0 //将K的每一位存到K_nums数组中
temp_K=K;
int[] K_nums=new int[K_digits];
for(int i=K_digits-1;i>=0;i--){
K_nums[i]=temp_K%10;
temp_K=temp_K/10;
} //初始化K_Answer数组,用于存储试填入其中的数,-1表示不存在
int[] K_Answer=new int[K_digits+1];
for(int i=0;i<K_digits;i++){
K_Answer[i]=K_nums[i];
}
K_Answer[K_digits]=-1; //将nums中出现的数字存到标记数组existNums中表示其存在
boolean[] existNums=new boolean[10];
for(int i=0;i<10;i++){
existNums[i]=false;
}
for(int i=0;i<nums.length();i++){
char a=nums.charAt(i);
if(a>='0'&& a<='9'){
existNums[a-'0']=true;
}
} //扫描K_nums,K_nums[p]表示当前扫描到的数字
int p=0;
while(p<K_digits){ boolean isrollback=false;
int findResult=-1;
findResult=findBigOrEqual(K_Answer[p],existNums); K_Answer[p]=findResult; if(findResult>K_nums[p]){
//如果查找的结果大于K中的值,则直接生成后续数字
int exist_min=-1;
for(int i=0;i<10;i++){
if(existNums[i]){
exist_min=i;
break;
}
} for(int i=p+1;i<K_digits;i++){
K_Answer[i]=exist_min;
} break;//跳出扫描 }
if(findResult==K_nums[p]){
//如果查找的结果等于K中值 //如果全部相等
if(p==K_digits-1){ findResult=findBigOrEqual(findResult+1,existNums);
if(findResult!=-1){
K_Answer[p]=findResult;
break;
}else{
isrollback=true;
} }else{ p++;
} }
if(findResult==-1){
//如果查找结果为-1
isrollback=true;
} if(isrollback){
//如果查找的结果小于K中值,回退到上一位
p--;
if(p==-1){
//直接生成K_digits+1位的最小数
boolean exist_zero=false;
int nonZeroMin=-1; for(int i=0;i<10;i++){
if(existNums[i]){
if(i==0){
exist_zero=true;
}else{
nonZeroMin=i;
break;
} }
}
//整个existNums中不存在非零数
if(nonZeroMin==-1){
return -1;
}
K_Answer[0]=nonZeroMin;
for(int i=1;i<K_digits+1;i++){
if(exist_zero){
K_Answer[i]=0;
}
else{
K_Answer[i]=nonZeroMin;
}
} break;//退出扫描
} K_Answer[p]++; } } //构造int型结果
int result=0;
for(int i=0;i<K_digits+1;i++){
if(K_Answer[i]==-1)
break;
result=result*10+K_Answer[i]; } return result; } //查找>=p的最小数,查不到返回-1
private int findBigOrEqual(int p,boolean[] existNums){
for(int j=p;j<10;j++){
if(existNums[j]){
return j;
}
}
return -1;
}
Question6:19本书,编号从1-19。从中抽五本,任意相邻两本不是相邻编号的情况有多少种。
Answer:
解法一:假设从19本书中拿出5本,结果剩下14本书,这14本书一共有14+1个间隔空位,在这些空位中选出5个,将5本书放回,则5本书均不会相邻。(本题是一个数学问题),
解法二:
/*
* 表示从n本书中抽取m本书,m本书的位置不相邻
*/
public int extractBooks(int n, int m){
if( m>0 && n>=2*m-1 ){ //剪枝
if(n==2*m-1){
return 1;
} if(m==1){
return n;
} int result=0;
for(int i=n-2;i>=2*m-3;i--){
result+=testScript4(i,m-1);
}
return result;
} return 0; }
Probleam7;玩过KOF(拳皇)的人都知道,玩的时候会连招是比较强的。题目的大概意思是:每招用一个大写字母表示,如ABC...Z,现给定n个连招公式:S→T,其中S长度为m,T的长度为1。在前m招的时候可以随便连,但m+1招后就必须遵循连招公式。现在要写一个算法,计算最长连招的长度;如果可以无限连招,则返回def。1≤n,m≤100
给了一个例子:n=4,m=3,连招公式为:ABC→C,ABC→D,CCA→A,BCC→A(最后一个连招公式忘了,记在纸上落在住处了,晚上改改,不过应该不影响理解)。连招公式的意思是:A、B、C可以连出C,也可连出D,C、C、A可以连出A,B、C、A、可以连出B。这时候可以得到最长连招公式:ABC→C→A→A,即最长连招公式长度为6。
题目要求给出算法思想并结合一定的伪码。
Answer(java):
//初始时start=””
private String kofMax(String start,List<String> movelist,int typelen){ //初始化最大长度maxlen和最大结果max
int maxlen=start.length();
String max=start; for(String nextmove:movelist){
if(start.length()==0|| nextmove.startsWith(start.substring(start.length()-typelen))
){
//如果找到下一招
//如果下一招已经在当前出招链中出现过,则出现循环
if(start.indexOf(nextmove.substring(nextmove.length()-typelen))!=-1){
return start+"eof";
} String str=null;
if(start.length()==0){
str=nextmove;
}else{
str=start.substring(0,start.length()-typelen)+nextmove;
}
//递归
String temp=kofMax(str,movelist,typelen); //如果出现循环
if(temp.endsWith("eof")){
return temp;
}
//进行比较
if(temp.length()>maxlen){
maxlen=temp.length();
max=temp;
} }
} return max; }
Question8:给定两个大小分别为n,m的整数集合,分别存放在两个数组中int A[n],B[m],输出两个集合的交集
Answer(java):
private int[] interSection(int[] array1,int[] array2){
//1.对array1和array2进行快排
quicksort(array1,0,array1.length-1);
quicksort(array2,0,array2.length-1); //2.扫描求交集
Int len=array1.length<array2.length?array1.length:array2.length;
int[] temp=new int[len];
for(int i=0;i<len;i++){
temp[i]=-1;
} int i=0,j=0,p=0;
while(i<array1.length && j<array2.length){ if(array1[i]<array2[j]){
i++;
}else if(array1[i]>array2[j]){
j++;
}else{
temp[p]=array1[i];
p++;
i++;
j++;
} }
//返回结果集合
int[] result=new int[p];
for(int k=0;k<p;k++){
result[k]=temp[k];
}
return result;
}
Qustion9:对数值范围为0到n^2-1的n个整数进行排序,请详细描述算法(若引用经典算法也需要给出具体实现),并分析算法的时间复杂度和空间复杂度。要求时间复杂度尽量优化,在此前提下空间复杂度尽量优化。
Answer(java):
由于给定的数值范围特殊,考虑到如果将n个数以n为基进行转化则最多两位,然后进行基排序,其时间复杂度为O(n),相当高效。其基排序实现如下:
private void radixsort(long[] peng,int n){
Node[] start=new Node[n];//start是对象数组
Node[] end=new Node[n];//end是引用数组 for(int i=0;i<n;i++){
start[i]=new Node(0,null);
end[i]=start[i];
} //扫描所有的数,将其转化为链表,头为head
Node pre=new Node(peng[0],null);
Node head=pre;
for(int i=1;i<peng.length;i++){
Node node=new Node(peng[i],null);
pre.next=node;
pre=node;
}
//进行若干次分配和收集,智能处理数的位数
boolean isOver=true;
for(int i=0;;i++){ Node p=head;
//分配
while(p!=null){
long b=p.data;
for(int j=0;j<i;j++){
b=b/n;
}
int c=(int)b%n;
if(c!=0){
isOver=false;
}
end[c].next=p;
end[c]=p;
p=p.next;
}
if(isOver){
break;
}
isOver=true; end[n-1].next=null;//此句目的是将最后的节点的next置空 //链接
for(int j=n-1;j>0;j--){
end[j-1].next=start[j].next;
start[j].next=null;
end[j]=start[j];
} head=start[0].next;
start[0].next=null;
end[0]=start[0];
}
//返回结果
Node p=head;
int i=0;
while(p!=null){
peng[i]=p.data;
i++;
p=p.next;
}
}
private class Node{
public long data;
public Node next;
public Node(long data, Node next) {
this.data = data;
this.next = next;
} }
Question10:假设银行有4个柜台,假设某天有200位顾客来办理业务,每个顾客到达银行的时间和业务处理时间分别用两个数组arrive_time和process_time来描述。
请写程序计算所有客户的平均等待时间,假设每个客户在去到营业部之后先拿号排队,然后在任意一个柜台有空闲的时候,号码数最小的客户上去办理,假设所有客户拿到号码之后不会因为银行众所周知的慢而失去耐心走掉。
Answer(java):
private void bankdeal(Node[] clients){
int currentTime=0;
final int counterNum=4;
//isfree和counterEndTime记录对应的柜台是否有空以及其结束业务时间
boolean[] isfree=new boolean[counterNum];
for(int i=0;i<isfree.length;i++){
isfree[i]=true;
} int[] counterEndTime=new int[counterNum];
for(int i=0;i<counterEndTime.length;i++){
counterEndTime[i]=currentTime;
}
//有没有方式对数组一次赋全值 //扫描每一个client
int i=0;
while(i<clients.length){
//检查那个counter可以用
for(int j=0;j<counterNum;j++){
if(isfree[j]){
currentTime=currentTime<clients[i].arriveTime?clients[i].arriveTime:currentTime;
int endtime=currentTime+clients[i].dealTime;
counterEndTime[j]=endtime;
clients[i].endTime=endtime;
isfree[j]=false;
i++;
}
}
//求出counters结束业务最早的那个
int minCounterEndTime=counterEndTime[0];
int minflag=0;
for(int k=0;k<counterNum;k++){
if(counterEndTime[k]<minCounterEndTime){
minCounterEndTime=counterEndTime[k];
minflag=k;
}
}
isfree[minflag]=true;
currentTime=minCounterEndTime;
} }
//顾客节点
private class Node{
int arriveTime;
int dealTime;
int endTime;
}
google的几道面试题的更多相关文章
- 《Google软件测试之道》基础
<Google软件测试之道>,一直听朋友讲起这本书,出于琐事太多,一直没机会拜读,最近部门架构觉得我们IT部门的技术太low,就给我们挑选了一些书籍,让我们多看看... 个人的一种学习习惯 ...
- google软件测试之道--读后笔记
看完google软件测试之道,以前有认真看过一次,今天又重新看了一遍. 在google,测试人员严格区分为SET和TE.SET前期深度参与项目的开发,推动开发人员的自测,从破坏者的角度寻 ...
- Java中ArrayList相关的5道面试题
本文参考了 <关于ArrayList的5道面试题 > 1.ArrayList的大小是如何自动增加的? 这个问题我想曾经debug过并且查看过arraylist源码的人都有印象,它的过程是: ...
- 小课堂week14 Google软件测试之道
读<Google软件测试之道> 在IT领域,Google是一面旗帜,是一家非常善于思考善于尝试的公司.随着面临挑战的不断增大,传统的测试开展方式也越来越力不从心,这本书讲述的就是一次完整的 ...
- ASP.NET 经典60道面试题
转:http://bbs.chinaunix.net/thread-4065577-1-1.html ASP.NET 经典60道面试题 1. 简述 private. protected. public ...
- 嵌入式C开发人员的最好的0x10道笔试题
嵌入式C开发人员的最好的0x10道笔试题 2006-11-22 15:53 约定: 1) 下面的测试题中,认为所有必须的头文件都已经正确的包含了 2)数据类型 char 一个字节 1 byte int ...
- google软件测试之道读后感(一)
这几天在抽空读一本新书,久负盛名的<google软件测试之道>.之前在网络上一点一点地看过它的英文版,很受触动,还做了很长的读书笔记,现在看到了中文版,才恍觉之前的好些理解存在不恰当的地方 ...
- 《Google软件测试之道》【PDF】下载
<Google软件测试之道>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382198 内容介绍 每天,Google都要测试和发布 ...
- Java 208 道面试题:第一模块答案
目前市面上的面试题存在两大问题:第一,题目太旧好久没有更新了,还都停留在 2010 年之前的状态:第二,近几年 JDK 更新和发布都很快,Java 的用法也变了不少,加上 Java 技术栈也加入了很多 ...
随机推荐
- HTML5+Bootstrap 学习笔记 2
navbar升级 从Bootstrap 2到Bootstrap 3 1. .navbar-inner已从Bootstrap 3中去除. 2. <ul class="nav"& ...
- nginx原声方法按照每天日志切割保存
首先配置日志变量,然后配置日志 在/etc/nginx/conf.d/default.conf 配置变量 server{ if ($time_iso8601 ~ "^(\d{4})-(\d{ ...
- 20181120-4 Beta阶段第2周/共2周 Scrum立会报告+燃尽图 01
此作业要求参见https://edu.cnblogs.com/campus/nenu/2018fall/homework/2409 版本控制地址 https://git.coding.net/lg ...
- Xftp安装和使用的视频录制方法
内容: 1.使用工具 2.操作步骤及方法 视频地址: http://v.youku.com/v_show/id_XMzEwNjg2MTg2NA==.html?spm=a2h3j.8428770.341 ...
- MacBook Pro 15寸常见问题及修复
苹果MacBook Pro更换SSD硬盘攻略教程 MacBook pro开机黑屏解决 苹果电脑 MAC PRO 开机黑屏了 MacBook Pro 开机后黑屏,怎么办啊 如果 Mac 无法开机 Mac ...
- 0429团队项目-Scrum团队成立
Scrum团队成立 团队名称:开拓者 团队目标:努力让每一个小伙伴在学会走路的基础上学会跑. 团队口号:我们要的只是这片天而已. 团队照:正面照+背影照(那就是为什么组名叫开拓者) 5.2 角色分配 ...
- Objective - C 之延展
延展:为已有的类新增私有方法,只能在本类中使用 一.创建过程: 二.总结: 1.延展只有.h文件,在其中写新方法的声明,在原本的类(Person)中写方法的实现: 2.上述的方法其实很不安全,因为如果 ...
- Hibernate学习--hibernate延迟加载原理-动态代理(阿里电面)
在正式说hibernate延迟加载时,先说说一个比较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它 ...
- TDDL调研笔记
一,TDDL是什么 Taobao Distributed Data Layer,即淘宝分布式数据层,简称TDDL .它是一套分布式数据访问引擎 淘宝一个基于客户端的数据库中间件产品 基于JDBC规范, ...
- DHCP:动态主机配置协议
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作, 主要有两个用途:给内部网络或网络服务供应商自动分配IP ...