谷歌面试题
实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).不能使用额外的数据结构。 (即只使用基本的数据结构)
解答
首先,你可以问面试官,构成字符串的字符集有多大?是ASCII字符,还是只是26个字母? 还是有更大的字符集,对于不同的情况,我们可能会有不同的解决方案。
如果我们假设字符集是ASCII字符,那么我们可以开一个大小为256的bool数组来表征每个字 符的出现。数组初始化为false,遍历一遍字符串中的字符,当bool数组对应位置的值为真, 表明该字符在之前已经出现过,即可得出该字符串中有重复字符。否则将该位置的bool数组 值置为true。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | boolisUnique1(strings) { boola[256]; memset(a,0,sizeof(a)); intlen=th(); for(inti=0;i<len;++i) { intv=(int)s[i]; if(a[v])returnfalse; a[v]=true; } returntrue; } |
该算法的时间复杂度为O(n)。我们还可以通过位运算来减少空间的使用量。 用每一位表征相应位置字符的出现。对于ASCII字符,我们需要256位,即一个长度为8的 数组a即可。这里的关键是要把字符对应的数字,映射到正确的位上去。比如字符’b’对应的 代码是98,那么我们应该将数组中的哪一位置为1呢?用98除以32,得到对应数组a的下标: 3。98对32取模得到相应的位:2。相应代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | boolisUnique2(strings) { inta[8]; memset(a,0,sizeof(a)); intlen=th(); for(inti=0;i<len;++i) { intv=(int)s[i]; intidx=v/32,shift=v%32; if(a[idx]&(1<<shift))returnfalse; a[idx]|=(1<<shift); } returntrue; } |
两个算法的本质其实是一样的,只不过一个用bool单元来表征字符出现,一个用位来表征。 完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include <iostream> #include <cstring> usingnamespacestd; boolisUnique1(strings) { boola[256]; memset(a,0,sizeof(a)); intlen=th(); for(inti=0;i<len;++i) { intv=(int)s[i]; if(a[v])returnfalse; a[v]=true; } returntrue; } boolisUnique2(strings) { inta[8]; memset(a,0,sizeof(a)); intlen=th(); for(inti=0;i<len;++i) { intv=(int)s[i]; intidx=v/32,shift=v%32; if(a[idx]&(1<<shift))returnfalse; a[idx]|=(1<<shift); } returntrue; } intmain() { strings1="i am hawstein."; strings2="abcdefghijklmnopqrstuvwxyzABCD1234567890"; cout<<isUnique1(s1)<<" "<<isUnique1(s2)<<endl; cout<<isUnique2(s1)<<" "<<isUnique2(s2)<<endl; return0; } |
如果字符集只是a-z(或是A-Z),那就更好办了,用位运算只需要一个整型数即可。
1 2 3 4 5 6 7 8 9 10 11 12 | boolisUnique3(strings) { intcheck=0; intlen=th(); for(inti=0;i<len;++i) { intv=(int)(s[i]-'a'); if(check&(1<<v))returnfalse; check|=(1<<v); } returntrue; } |
【JAVA实现】
1 2 3 4 5 6 7 8 9 | publicstaticbooleanisUniqueChars(Stringstr){ intchecker=0; for(inti=0;i<th();++i){ intval=At(i)-‘a’; if((checker&(1<<val))>0)returnfalse; checker|=(1<<val); } returntrue; } |
1 2 3 4 5 6 7 8 9 | publicstaticbooleanisUniqueChars2(Stringstr){ boolean[]char_set=newboolean[256]; for(inti=0;i<th();i++){ intval=At(i); if(char_set[val])returnfalse; char_set[val]=true; } returntrue; } |
-
文艺部面试三分钟8篇
文艺部面试三分钟1我对这个世界从来都不缺少幻想,但幻想与现实的巨大差距,促使我不得不打起十二分的精神与热情投入到追求理想的工作去。我喜欢挑战,喜欢为人所不能,喜欢打破墨守成规的.旧俗,因为,我有着一颗永不服输的心!在高中时期,我就通过面试当选了学校文艺部部...
-
邮政储蓄银行面试内容优秀
邮政储蓄银行面试内容优秀1邮政储蓄银行面试答题技巧。1、请介绍一下你自己((这题一定要背下来,基本上银行面试都要考,至于你的个人资料在档案上都有,所以考官问你这个题并不是要问你身高三围,侧重点在你为什么要报考这家银行)回答要点:各位考官大家好,我叫XXX,今年26岁,...
-
跳槽面试注意事项
跳槽面试注意事项1一、跳槽面试需要注意什么跳槽后面试时,通常会被问到的一个题目是——请描述一下你离开以前所供职单位的理由。这就需要我们集中智慧,巧妙的避开陷阱。“你为什么要离职?”在回答这个问题时应该集中精力。像人员臃肿阻碍了能力发挥、上班路途太...
-
面试需注意哪些礼仪
面试需注意哪些礼仪1(1)进门时要表现得自然,不要紧张或慌张;(2)面试时要始终面带笑容,谦恭和气。表现出热情、开朗、大方、乐观的精神状态;(3)不要无缘无故皱眉头或毫无表情;(4)不要直盯对方,也不要以眼瞟人、漫不经心,眼光宜落在主考人的鼻子上为佳,这样既保持了接触...