暑期实习面试 算法题/编程题记录

本篇用于记录面试过程中遇到的算法题和编程题。
我在找实习过程中看了很多人的面经,学到了很多知识,很幸运能获得前人的经验,因此我也稍微留下一点点东西。
八股、场景题我都不擅长,算法和编程题我还是回答得比较好的。
介绍一下背景:西北农林科技大学本科,ACM EC银 regional 银

淘天 客户端开发一面:
    题面:
        给一副牌,可能有重复,判断是否存在顺子。
    做法:
        桶排序去重,然后看是否有连续的5张牌,最后特判10 J Q K A。这样写复杂度是严格不超过牌数的。
    现场情况:
        我当时也写了上文提到的方法,没什么问题。

字节 后端开发一面:
    题面:
        滑动窗口,给一个数组,长度为K的滑窗,求每个滑窗最大值。
    做法:
        很经典的题,我的写法是双端单调队列,队列一端控制窗口不越界,另一端控制队列里的数字均为有效。
        举个例子,一对下标i,j(i<j),如果nums[j]>=nums[i],那么i就没有存在队列里的必要了,可以出队。

    现场情况:
        我写的就是上文的做法。然后面试官让分析了复杂度,这样做复杂度是O(n)的。
        面试官问了一下有没有优化的空间。
        我当时队列大小是数组长度,提出将队列换成双端队列,动态大小,这样额外空间不超过O(K)。
        而且代码里我是单独处理了前K个元素,后来换了个写法,在一个for循环里处理完。

非常建议大家记一点优化,可以不会具体怎么做,写的代码也可以非完美,但面试官问如何优化时要能说出点东西。
具体优化思路:
代码方面(冗余代码,太多if,变量名称,有没有好的方法写短点)
时间方面(有没有复杂度更低的做法,不知道怎么优化可以指出当前代码复杂度瓶颈在哪,即哪一部分用的最多,可以直接诚恳地说不懂,但觉得这里可以优化)
空间方面(是否使用了定长数组,尽量用多少空间开多少空间,能不能不用额外空间等等)

字节 后端开发二面:
    题:
        给一个十进制数n,和一个包含若个1位数的数组,用数组中的数字组成小于n的最大数。
    做法:
        分情况讨论+贪心。
        如果本题是不超过n,先看看不超过n怎么做,从高位往低位考虑。
        每次从数组里选一个能填的最大值,如果某一位填的数字没有n上的数字大,那么后面的位均可以填最大数。
        特殊处理最高位找不到合法数字的情况,假设n是x位数,这时候答案就是x-1个数组里的最大数。
        特殊情况里还需要特判x=1的情况,这时候无解。
        如果小于n,特殊情况是不变的,我们可以先按照不超过n的方法构造出一个解,如果此时解满足小于n,直接输出。           否则从低位往高位找到第一个可以填写小于n对应位数字的位置,如果有则修改该位,其余低位填上最大数。
        如果找不到这样的位置,那就输出x-1个数组最大数。

    现场情况:
        我一开始没有考虑任何特殊情况,写完贪心之后自己出数据的时候想到了特殊情况,直接把代码推翻重写。
        好在前面写得比较快,总共用了20分钟完成所有情况的讨论。
        面试官问了我思路,并且让我说了一下复杂度,其实严谨复杂度就是O(10*log_10(n))
        然后解释了一下复杂度的含义,log_10(n)是n的位数,1位数数组大小不超过10,面试官表示没什么问题。

字节 后端开发三面:
    题1:
        给一个字符串s,和一个字符串数组arr,问字符串能否由数组里的串组成。
    做法:
        动态规划,将arr里字符串存入哈希表,枚举s的每个子串去哈希表里找是否出现。
        如果出现就用链表连一条子串头到子串尾的边。
        设dp[i]表示s的前i个字符是否能被匹配,转移方程就是dp[i]转移到dp[j](j>i),当且仅当i+1到j有连边。
        这样做复杂度是O(n^2 hash())的,这里hash()是和你选择的哈希表有关,我用的是C++的map,所以是log
    现场情况:
        我写的也是动态规划,但是判断串是否出现用了map。面试官问复杂度,这里直接说了n^2logm
        其中n=len(s),m=arr.size(),面试官不太满意,问了一下优化。
        我当时并没有特别严谨想过这个优化问题,我首先考虑的瓶颈是判断每个子串是否出现这部分。
        给面试官说了这个瓶颈,表示认同。我说可以试试AC自动机优化这个匹配过程。面试官赞同。反问,回答用哈希。
    
    题2:
        设计一个数据结构,满足:①O(1)插入、修改、删除;②能够按照插入顺序遍历元素。
    做法:
        这里很明显每个元素有两个顺序,一个是结构顺序,一个是插入顺序。
        开两个链表+哈希表分别表示两个结构即可,和跳表有点像。
    现场情况:
        我一开始回答得差不多。面试官反问了为什么哈希表是O(1)的。
        回答哈希表并不是严格O(1),而是均摊O(1),如果数据过大或者哈希函数不合适或者冲突不合适,复杂度也会高。
        再问如果数据类型是字符串该怎么哈希,回答将哈希映射成一个高进制数,用自然溢出或者取特殊模数。
        取双哈希,双种子等方法增强哈希强度。

    题3:
        n个数字,数字范围[0,m],求任意两数异或和的最大值。
    做法:
        0/1字典树经典问题,将数字转成0/1串,高位往低位插入字典树中,查询时尽量往异侧走,这样异或值最大。
    现场情况:
        看到题10分钟内写完了。
        面试官问了问复杂度,复杂度是O(nlogm)
        然后讲了讲做法就没了。

腾讯 后台开发一面:
    题1:
        给一个没有括号的四则运算表达式,求值
    做法:
        经典栈模拟题。
    现场情况:
        写了栈做法,并讨论了除以0的情况。面试官范围如果字符串非法怎么办。忘记考虑了,回答增加合法性判断

    题2:
        给一个数组,问是否存在满足和为K的倍数的子数组
    做法:
        前缀和套路题,在模K意义下求前缀和,只有有某一种前缀值出现2次,那就有解。
    现场情况:
        和上面做法一致,加上map判断,其实可以用哈希表,但面试官没有追问。

    题3:
        给一个数组,只有两个数字出现1次,其他数字都出现2次。求对应的两个数字。
    做法:
        求异或和,得到的异或值肯定非0,异或和里任意找某个非0二进制位,将数组按这一位分类异或。
        得到的两个异或和即为答案。
    现场情况:
        和上面做法一致,给出了为什么异或和一定非0的证明。三道题只用了20分钟,面试官没有追问。

还有一些其他厂的,面完没复盘就不记得了,想起来再补充。

面试里的算法、编程题,我感觉还是需要一些trick的,遇到的题目几乎都是很有章法的题。
在面试时编程部分算是我的舒适区,每次都在编程题这里找回场子,大部分面试官都挺满意我编程题的表现。
不过不是很清楚这样的表现能否为面评加分...在与一些其他竞赛选手交流的时候发现,奖项的作用是使面试时遇到的题目变难,以及更加严格的要求,写出题是理所应当,写不出就是巨大减分项。
所以整体来说,面试的时候我写编程题还是很紧张的,虽然目前没有遇到过让我思考超过1分钟的题目,但我还是不感到轻松,每次知道做法之后都在绞尽脑汁想合法性、想corner case、如何让代码优美一点、如何增加可读性...

最后祝大家面试顺利,拿到想要的offer
全部评论

相关推荐

07-04 17:12
已编辑
门头沟学院 Java
1.&nbsp;我看你是做服务端的,但是你投的是客户端开发,你后面是倾向于安卓还是IOS?2.&nbsp;get和post的区别是什么?3.&nbsp;实现用户登录功能该用post还是get?为什么用post?post就安全吗?body不也可以通过抓包看见吗?3.&nbsp;HTTPS加密的过程?我答的是公私钥结合的方式其实就是TLS协议交换密钥的过程。追问如果代理人攻击如何解决?提示CA证书机制没答出来具体的机制是如何实现的4.&nbsp;TCP三次握手,为啥不是二次握手?为啥不是四次握手,这样岂不是更能保证可靠我说四次的话,感觉没有必要三次就能保证建立连接的可靠5.&nbsp;UDP协议在那一层?那我传输的时候可不可以绕过UDP协议直接交给IP层?这里没答好正确答案应该是,传输层负责端到端的通讯,屏蔽底层细节,通过ip协议可以把数据传输到对应的主机,但是如果没有端口信息不能定位到具体主机的应用进程,还有就是传输层的作用,可靠传输、拥塞控制、流量控制5.&nbsp;线程和进程的区别?线程与线程之间是共享内存的吗?进程与进程之间呢?6.&nbsp;hashmap的put和get过程7.arraymap&nbsp;和hashmap如何选型的?我不知道arraymap&nbsp;是什么java中没有后来才知道是客户端的8.&nbsp;equal和hashcode那些经典八股9.&nbsp;如何判断一个对象能否被垃圾回收?可达性分析算法&nbsp;gcroot,那些可以作为gcroot?虚拟机栈和本地方法栈中引用的对象、方法区中静态属性引用的对象和方法区中常量池引用的对象10&nbsp;.垃圾回收机制,分代回收机制,老年代新生代那一套11&nbsp;.threadlocal&nbsp;底层实现原理12&nbsp;.单例模式懒汉和饿汉的区别?然后分别用在那些场景中,你实际用的话?13&nbsp;.为啥设计双亲委派机制手撕1.单例模式2.删除链表重复元素手撕2翻车其实是有点紧张加上第一次面字节,也不太习惯飞书的编译器,双指针一直有BUG很慌就没调出来,反问还有那些需要提升的点?面试官说基础知识掌握还可以,编码习惯有待提升,下去再练练吧。败在了本来最擅长的点😣,这手撕已经很给我机会了,自己没把握住
查看16道真题和解析
点赞 评论 收藏
分享
找实习期间看了不少大佬们分享的面经,收获不少,牛客上好像没什么银之心的面经,所以简单分享下自己的经验。bg:985本,211硕,简历包含一段小厂的unity实习,一个UE的基于GAS的ARPG玩具demo,4月底开始投简历。----------------------------------------------------------------------------------------------Time&nbsp;Line:5.23&nbsp;--&nbsp;笔试5.29&nbsp;--&nbsp;1面5.30&nbsp;--&nbsp;2面6.3&nbsp;--&nbsp;3面6.6&nbsp;--&nbsp;hr面6.16&nbsp;--&nbsp;oc---------------------------------------------------------------------------------------------笔试:4道算法题1.给定一个排列,求出所有子区间的中位数之和2.给定两个字符串a,b,将b插入a使得字符串为回文串,求有多少种插入方法3.给定两个长为n的整数数列A,B,每次可以从A的左或者右端取一个数字,B按顺序取,假设第i次取走的数为ai,则第i次取走的价值为bi*ai,求最大价值和4.给定两个长度相同的字符串s,t,每次可以将任何位置的任何字符移动到字符串末端,求至少需要多少次操作可以市s变成t?---------------------------------------------------------------------------------------------面试体验很好,几个面试官相当专业,反问环节回答得很认真,不敷衍,收获良多;hr小姐姐推进流程和回复问题也很及时。------------------------------------------------------------------------------------------------一面(55min)1、自我介绍2、常规的C++八股拷打,这里推荐知乎&nbsp;不羁的游侠&nbsp;的&nbsp;《计算机基础篇》&nbsp;,我自己面试过程中遇到的大部分c++八股都可以在里面找到。-----没答上来或者答得不好的几个问题:(1)一个子类继承了两个父类,两个父类中有同名的虚函数,子类中重写此虚函数,重写的是哪个父类的虚函数?(2)类模板的声明和实现可以分别放到头文件和cpp中吗,为什么?(3)执行exe,main函数是最先执行的吗?如果不是,举几个在main函数前执行的例子。3、问:你的项目里有用行为树实现的敌人AI,有看过源码吗?答:没有,不过知道AI寻路的一些过程和原理,(然后balabala开始讲NavMesh生成网格体的过程和A*算法)4、问:了解过动画系统中动画动起来的原理吗?答:动画的载体是骨骼,动画序列由时间轴上的一系列关键帧组成,每个关键帧存储了每根骨骼的变换信息,非关键帧的骨骼变换信息通过插值等方式可以计算出。问:介绍一下UE的动画状态机、混合动画、叠加动画?&nbsp;&nbsp;&nbsp;&nbsp;答:知乎&nbsp;TurBo强&nbsp;&nbsp;的《UE&nbsp;动画系统框架介绍及使用》;问:知道蒙皮动画吗?&nbsp;&nbsp;&nbsp;答:没了解过问:看过动画系统源码吗?&nbsp;&nbsp;&nbsp;答:&nbsp;没有5、手撕算法题:(1)字符串加法,常规题(2)追加要求:两个数可以是负数询问面试官:能否拆分为两个正数的减法和加法的函数,计算前先单独处理运算的两个数的符号位,并调用相应的函数。面试官回答可以,写了5min没写完,面试官表示时间差不多了,直接进入反问环节。----------------------------------------------------------------------------------------------------二面(45min)1、自我介绍2、问:玩过什么游戏?答:最近在玩&nbsp;最后纪元&nbsp;,一个暗黑风格的ARPG游戏3、问:这种ARPG游戏里,怎么对敌人造成伤害?答:比如玩家发射一个火球,需要为火球添加碰撞体,敌人身上也必须具备碰撞体,同时实现接受伤害的接口,当火球与敌人碰撞时,触发hit或者Overlap事件,传递碰撞信息,其中包括敌人对象,拿到敌人对象后,调用接受伤害的接口。4、问:怎么进行碰撞检测?答:粗略检测的话,可以用包围盒等包围需要检测碰撞的对象,然后检测两个包围盒是否有相交即可。过程中可以通过四叉树、八叉树或网格加速结构,快速排除远距对象。不同划分区域保证不会碰撞的情况下,就能快速过滤与本物体不同区域的其他潜在物体碰撞。问:包围盒和包围球间的范围检测哪种比较简单答:包围盒和包围盒吧,只需要把各个顶点投影到坐标轴上。(好像不对,应该是球和球?)问:球和球的范围检测怎么计算?球和盒的范围检测怎么计算?答:(几何知识,大概画个图就知道了)5、问:如果是近战攻击,怎么对敌人造成伤害?答:和远程差不多,不过是需要在近战武器上添加碰撞盒,创建两个场景组件放置在武器的两端,作为box&nbsp;trace的起点、终点,挥舞武器的时候,在两点之间执行box&nbsp;trace。问:怎么让box&nbsp;trace跟着武器动的?答:近战攻击用一个动画蒙太奇实现,武器绑在角色手上的slot里,碰撞盒和起点、终点是武器的子组件,动画动,武器跟着动,子组件也跟着动。6、问:项目里有实现自动寻路吗?有了解过吗?答:(一面的时候也问道了)NavMesh生成网格体的过程+A*算法。问:如果场景中有移动的障碍,怎么处理?答:不太清楚&nbsp;,不过我猜可以先划分区域,只更新移动物体影响的区域,更新寻路网格体时,把移动障碍和其移动覆盖的区域整体标记为障碍物。问:需要重新烘焙吗?答:需要。7、问:还做过其他什么东西吗?答:还做了一个简单的多人游戏项目,不过做得不是很好问:网络游戏用什么协议答:UDP,不过通常会将在其往TCP的方向改,即可靠的UDP,(序列号与确认,丢包重传、超时重传、滑动窗口、拥塞控制)8、无手撕环节---------------------------------------------------------------------------------------------------三面(30min)三面大部分时间聊聊天了,问了一些简历上提到的东西,比如MVC的难点,ui的MVC和工程上的MVC的关系等,有三分之一的时间是面试官在给我讲解反问环节问的问题,醍醐灌顶,可惜忘记录音了...-------------------------------------------------------------------------------------------------
duadua666:同银之心oc,但是怎么感觉我这问的这么简单😧
查看25道真题和解析
点赞 评论 收藏
分享
评论
4
8
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务