技术岗面试笔试算法题详解(一)

来源:互联网 发布:淘宝被挤爆了图片 编辑:程序博客网 时间:2024/06/06 12:45

序言

转眼间本人也是大四狗了,开始忙着找工作。
身为一个技术岗的java开发狗,不管是笔试还是面试都肯定会碰到算法题的。
那我干脆从今天开始把我找工作时碰到的算法题记录一下,算是做个复习吧。

金蝶国际软件集团有限公司

找最短时间

有一个隧道,只能同时通过两个人,而且必须用手电筒才能通过,不幸的是,有一群人想通过,但是只有一个手电筒。这些人通过隧道的速度可能不同,走得快的人得等走得慢的人。假设他们单独通过隧道的时间分别为T1,T2,T3,….,Tn,那么请设计一个算法,使他们通过的总时间最短。

那么这一道题,看上去很简单,好像只要让速度最快的那个博尔特来回跑就好了嘛对不对?
错。
由于每次通过的两个人,走得快的必须等走得慢的人,所以就会造成时间的浪费。
比如一个人通过这个隧道需要9s,另一个人通过这个隧道要10s,那么他们如果一起走,走得快的这个人的生命就会因为等待走得慢的这个人而流逝掉1s。。。咳,跑题了。
总之就是这个意思,(大前提)由于两个人速度不同,他们之间必然会产生时间差,他们的速度差距越大,那么他们时间差越大,即浪费的时间越多。
因此我们得到一个条件
(条件一)每次通过隧道的两个人速度接近
那么我们怎么选择那个来回传递手电筒的人呢?
很显然,我们要(条件二)找两边走得最快的那个人来传递手电筒
那我们第一次要让谁先走过去?显然,如果让走得最慢的两个人先过去,那么送手电筒回来的人最快也会是走得倒数第二快的人,意味着要让走得最慢的两个人走两次甚至两次以上。所以我们可以让钻隧道最快的两个人(假设他们叫A、B)来担任“火炬手”。则(条件三)A与B必须分别位于隧道两端
因此根据条件三第一次我们先让A把B送到隧道那一端,辛苦你们了!
接下来,我们根据条件二,让走得最快的兄弟A把手电筒送回来
这时候问题来了:根据条件一,接下来我们要送A和走得第三快的C一起过去吗?
显然不行,因为如果这么做每次和A一组的人的速度就会越来越慢,最后会出现A和走得最慢的人一组,并不符合我们的大前提的要求。
因此,我们需要从最慢的两组开始送过去,这样到最后最差情况也是A和C一组。
所以第二次我们把走得最慢的两个人送过去
之后根据条件二,我们让手电筒所在端走得最快的人(B)把手电筒送回来,这时我们发现,走得最快的两个人AB又在同一端了,于是我们让A把B再带到隧道那头,再回来接其他走得慢的人(累死了 )。
因此我们发现,每次都是AB先走,然后A回来,走得最慢的两个人过去,B回来,然后AB再过去,然后A回来,然后又是走得最慢的两个人过去。。。。一直循环直到最后隧道这头只剩下A或A和走得第三快的人,于是把最后两个人送过去。这就是这道题目的思路。

总结

简单来说,具体步骤就是这样:
1 把AB一起送到隧道那一端;
2 把那一端走得最快的人送回这一端;
3 判断AB是否在隧道这一端,如果是,走1;如果不是,走4;
4 如果这一端还有人,那么把这一端走得最慢的两个人送到那一端,跳2;否则结束。

恒生电子股份有限公司

找最长相同子串

给出两个字符串,要求输出两个字符串中长度最长的相同的子串,如果有多个长度相同的字串,则输出较短串中第一个出现的子串。

不得不说恒生出的题目确实比较简单,可能是因为线下笔试的原因,担心考生来不及吧。
我当时的做题思路是这样的。用两个for循环嵌套,外层循环较短串,内层循环较长串,当碰到相同的字符时,进入另一个函数。这个函数接收两个字符串与其当前所在的位置,并不断地将他们的下一个字符进行比较,同时记录比较出相同的个数temp。当遇到不相同的时候就return temp。再将temp和之前记录的最大子串长度Max进行比较,如果temp比较大就将temp赋值给Max,同时记录下最短串的当前所在位置。
一般是可以把两个字符串全部的字符循环一遍的,但是我们可以优化一下,每次进入内层循环之前,都先判断较短串里剩余的字符个数是否小于Max。如果小于Max,那么就可以break了。

总结

1 将较短串中的每个字符与长串中的每个字符进行比较;
2 相同,走3;不同,走8;
3 比较短串与长串的下一个字符是否相同;
4 相同,走3,temp+=1;不同,走5;
5 返回temp,与Max进行比较;
6 如果temp较大,则Max = temp,同时记录下较短串的当前位置MaxIndex;
7 判断较短串剩余字符是否小于等于Max;
8 小于等于,则break,输出subString(MaxIndex,MaxIndex+Max);否则走1;