-
-
<div>称球问题 12个一模一样的球,其中有一个坏球,或重或轻。问如果3次把此球找出 分3组每组4个球,第一次两两一称,最坏情况,天平不平衡。天平平衡的话很好处理,读者可以自己思考。 然后,将左侧的3个球拿下,把右侧的3个球放到左侧,再把底下的3个好球放到右侧。 进行枚举:天平可能出于3种状态,没有变化,变平衡,以及发生反向倾斜。 没有变化:很简单说明拿下去的3个球是好球。那么可以知道坏球只可能在天平上没动的两个球里,最后一次测出即可。 变平衡:说明3个坏球被拿下去了!呵呵,天平上所有的都是好球,且知道坏球是轻是重(从拿下去的3个球所在侧是偏重还是偏轻可以判断出来)。这样随便选俩一测即可。 反向倾斜:说明一个很关键的问题,就是坏球从一侧挪到另外一侧了,然后我们又可以知道拿3个球从一侧挪到了另外一侧,类似于变平衡的情况,找到坏球是重还是轻,然后一次测出。 老鼠问题 有1000瓶水,其中有一瓶有毒,小白鼠只要尝一点带毒的水24小时后就会死亡,至少要多少只小白鼠才能在24小时时鉴别出那瓶水有毒? 将瓶子编号,然后将编号表示成二进制,比如3就是0000000011,10位二进制对应10只老鼠,为1的喝为0的不喝 栈,push,pop,min操作 1.使用链表组织栈,每次push将新成员改为链表头,操作o(1); 2.每次pop将链表头弹出,第二个成员作为链表头,操作o(1); 3.如何求最小值? 这个问题要在常数内时间解决的话需要将这个链表做一个扩展,就是从空栈开始,每次push一个元素x后,获得当前最小值min(top担不pop);比较x与min,如果x<min 那么继续push x,表示pushx后的当前最小值为x;否则push min; 这样的扩展导致正常的push操作需要弹出当前最小元素和栈顶元素,同理每次pop的时候也是弹出两个。这样保证min的值始终是当前的最小。 n条线最多把平面分成多少份?那n个面最多把空间分成多少份? (1)一维情况:一条直线上有n个点,显然把这条直线分成n+1段。 (2)二维情况:即考虑平面上n条直线最多分得的平面块数。直线数为零时 有一个面,第k条直线与最多与前k-1条直线都相交,产生k-1 个交点,由(1)得这k-1个交点把这条直线分成k段,每段都使面的块数加1,那么n条直线最多分得的平面块数为1+1+2+3+...+n=(n+1)n/2+1。 (3)三维情况:用N个面切割一个空间,求最多切得的空间的个数。没有面时有一个空间,第k个面与前k-1个面相交产生k-1条交线,把这个面最多分成k(k-1)/2+1个面,每个面新产生一个空间。 故用N个面切割一个空间,切得的空间的个数为:1+1+2+4+7+...+(N(N-1)/2+1)=N+1+(1*2+2*3+3*4+4*5+...+N(N-1))/2 其中1*2+2*3+3*4+......N*(N-1)={1^2+2^2+3^2+......(N-1)^2+N^2}- {1+2+3+4+......+N-1+N}=(2N+1)(N+1)N/6-N(N+1)/2 带入上式化简得到(N^2-N+6)(N+1)/6 n*n的棋盘,每个格子上有一个数,要你从左上角出发,每次向右或向下走一步,最后走到右下角。问怎么找到一种走法,使得路径上的数的总和最大? 状态方程 f(i,j) = max(fi-1,j),f(i,j-1)); 边界条件 f(0,0) = a[0][0]; 如果是两个人走,每个人经过一个格子以后,那个格子里的数就变为0,那么怎么使两个人的总和最大? 甲随机走了一条路径 乙走最路径,求最大值 <h3 dir="ltr">最长上升/不降子序列N LOG(N)复杂度算法。</h3> 我们先来看一个例子 4 1 3 2 5 11 9 10 正常的思路是 定一个数组F[] 表示包含这个数字的最长子序列长度,然后每到一个数字a[i],找到比这个数小的第j个数a[j],且F[i] =max{ F[j]+1 }; 算法复杂度0(n^2). 如何来优化这个问题呢, 就是说如果让你找a[j]的时候更快,这里有个思路可以这样考虑: 定义一个数组C[] ; C[i] 记录长度为i的子序列的最大值。 则遍历到a[i]的时候 查看C[]中比a[i]要小的那个最大的数C[k](此处是效率的关键,用二分查找),C[k], 则F[i] =k+1; 然后C[F[i]] = min(a[i] ,C[F[i]] )。 模拟过程: 4 : F[0] = 1 ,C[1] = 4; 1: F[1] = 1, C[1] = 1; 3: (二分找到C[1]<2)F[2] = 1+1 = 2, C[2] = 3; 2: (二分找到C[1]<2)F[3] =1+1 = 2, C[2] = 2; 5: (二分找到C[2]<5)F[4] = 2+1 = 3, C[3] = 5; 11: (二分找到C[3]<11)F[5] =3+1 = 4, C[4] = 11; 9:(二分找到C[3]<9)F[6] = 3+1 = 4, C[4] = 9; 10: (二分找到C[4]<10)F[7] = 4+1 = 5, C[5] = 10; 按顺序输出C[] 1 2 5 9 10. <h1 dir="ltr">二叉树问题</h1> 在纸上写非递归中序遍历二叉树,如果不用栈只用父指针。 <div dir="ltr"> <table><colgroup><col width="*"></col><col width="*"></col></colgroup> <tbody> <tr> <td>void inOrder(Node* root) { stack s; while(root!=NULL&&!s.empty()){ while(root!=null){ <p dir="ltr">s.push(root);</p> <p dir="ltr">rootroot = root->left;</p> <p dir="ltr">}</p> <p dir="ltr">if(!s.empty()){</p> <p dir="ltr">s.pop(root);</p> <p dir="ltr">visit(root);</p> <p dir="ltr">rootroot =root->right;</p> <p dir="ltr">}</p> <p dir="ltr">}</p> }</td> <td>void inOrder2(Noder* root) { while(root!=null){ while(root-left!=NULL&&root->left->visited==false) { rootroot = root->left; } if(root!=null && root->visited==fasle) { visit(root); root->visited = true; } if(root->right!=NULL && root->right->visited==false) { rootroot = root->right; } else { rootroot = root->parent; } }</td> </tr> </tbody> </table> </div> 二叉树中找到中心点。(中心的定义:到其他点的距离之和最短) BST 删除节点 分为三种情况 1.如果删除节点无字节点,直接将删除节点用Null替换 2.如果删除节点只有左子树或者右子树,那么将删除节点的左(右)儿子的根代替他 3.如果删除节点有左右子树,那么找到左子树的最大节点(或者右子树的最小节点),将此节点代替删除节点即可。 <h1 dir="ltr">找出二叉树上任意两个结点的最近共同父结点。</h1> 1.问有没有父指针 2.没有父指针 采用后序遍历的方法;注意在一条路径上的情况,那么上面的就是下面的父节点。 后序思路 后序时候如果访问到了A且则返回1;回溯, 后序时候如果访问到了B且则返回2;回溯, 如果非A非B则返回0 每次访问节点本身时候已经获取左右子树的信息了,将返回值相加看是否=3如果为3此节点就是最近祖先。 如果未发现则继续回溯。 怎么判断两个链表是否相交?怎么判断链表是否有环? <p dir="ltr">求两个单链表是否相交,如果相交,求出交点</p> <p dir="ltr">将链表2接在链表1后面,判断链表是否有环,如果有,则相交,最后,当然不要忘记恢复原来状态,去掉第一个链表到第二个链表头的指向。</p> <p dir="ltr">判断交点d2:分别求链表1,2的长度x,y,假设x>y,则让链表1先前进x-y部,然后两个链表同时单步前进,并比较地址,如果相等,则为交点,返回。</p> <p dir="ltr">2求两个链表是否相交,如果相交,求出交点(存在环)</p> <p dir="ltr">a)链表1单步前进,链表2双步前进,当链表2的next指针等于链表一的当前地址时,两者相交</p> <p dir="ltr">b)求交点,从a中的一点,将换断开,逆序链表1,此时相当于生成3个新的链表,只要求出这三个链表的交点,链表1还原,再判断生成的两个不同交点,是否在链表2上</p> 猴子搬香蕉 前面每前进1米,就要3趟,也就是吃掉3个香蕉;当然不可能50米全部这样,因为没有150个香蕉够吃^_^ 这就需要找到一个点,当小猴子拿香蕉时能拿最多的香蕉(<=50),这样它可以一次到家,不用再往返。 设Y为要求的香蕉最大剩余数,X为要求的那个点(X米),可以列出方程式: 1. Y=(100-3X) - (50-X) 2. (100-3X)<=50 很容易求出Y=16 多边形面积 最好的解法 向量积叉乘 多矩形求面积算法 算法:单个矩形面积好求,但多个矩形进行重叠,这样形成的区域没有规律性,面积不好求。既然整体面积难求,就局部的进行求解(离散思想)。 对于输入的所有矩形,我们存储每个矩形的信息(对角的点坐标,存于rec数组中,两对角点为(rec0,rec1),(rec2,rec3)),然后定义两个一维数组x和y,用来存储所有矩形的所有的横坐标和纵坐标(每个矩形有两个横坐标和两纵坐标),之后对x和y中的元素分别进行升序排序,这样x和y中的坐标的依次组合能将平面分为多个区域。再定义一个二维数组flag。对于一个矩形((rec0,rec1),(rec2,rec3)),我们要找到一个x[i]和一个y[j],使它们满足x[i]>=rec0&&x[i]<rec2&&y[j]>=rec1&&y[j]<rec3,那么我们可以知道由x[i+1]->x[i]为横向,y[j+1]->y[j]为纵向所围成的区域在这个矩形中,此时,我们将这个区域的标置记为flag[i][j],并置flag[i][j]=1。 那么这块区域的面积s=flag[i][j]*(x[i+1]-x[i])*(y[j+1]-y[j]); 当我们沿着x和y数组顺序进行查找,并置相应的flag为1,而其它的flag为0(表示这样的区域没有被矩形覆盖,那么上式的s值为0),这样,将平面内所有离散后的区域的s加起来,就是我们要求的矩形并的面积了。 博弈问题 囚徒问题1 <p dir="ltr">两个嫌疑犯(A和B)作案后被警察抓住,隔离审讯;警方的政策是“坦白从宽,抗拒从严”,如果两人都坦白则各判8年;如果一人坦白另一人不坦白,坦白的放出去,不坦白的判10年;如果都不坦白则因证据不足各判1年。在这里,博弈者就是两个嫌疑犯,他们每个人都有两个选择,即坦白和不坦白。</p> 如果是你你会如何选择? 从个人的角度,A会做如下考虑:如果B不坦白 那么我坦白 不会被判,不坦白还会判1年,不划算;如果B坦白,我坦白只会被判8年,不然会被判10年;所以我还是坦白吧! B同时也是这么想的;所以A、B各被判了8年。 <p dir="ltr">人类的个人理性有时能导致集体的非理性。</p> 囚徒问题2 有100个无期徒刑囚徒,被关在100个独立的小房间,互相无法通信。 每天会有一个囚徒被随机地抽出来放风,随机就是说可能被抽到多次。 放风的地方有一盏灯,囚徒可以打开或者关上,除囚徒外,没有别人会去动这个灯。每个人除非出来防风,是看不到这个灯的。 一天,全体囚徒大会,国王大赦,给大家一个机会:如果某一天,某个囚徒能够明确表示,所有的囚徒都已经被放过风了,而且的确如此,那么所有囚徒释放;如果仍有囚徒未被放过风,那么所有的囚徒一起处死! 解法 有一个平均100*100 =10000天的算法: 编号1-100,1号负责开灯,2-100号负责关灯,且每人只能关一次;1号记下关灯次数。 如果关灯次数达到99次则他们就可以出笼了。 也就是说每个人大概随机到100次出来。大概10000/365 =30年左右。 囚徒问题3 有100个囚犯关在牢里,国王打算给他们一个机会,于是给他们一个看似不可能完成的任务: 让100个人每人头上戴一顶帽子,每顶帽子上随机的写上一个数字,数字的范围在0-99之间,囚犯们只能看到别人的帽子上的数字,看不到自己头上的数字。现在,国王要求他们每人同时写一个数字(无法知道别人写的数字,而且不得用任何方法提供信息给别人),如果100个人当中至少有一个写对了自己头上的数字,那么全体获释,否则全体杀头!在这之前给他们一点时间,让他们讨论一个方案。请问如果您是其中一个囚犯,您能想出一个100%获释的方案吗?请说说您的方案是什么? 解法:利用同余定理 if(a = b (mod p) and c =d (mod p)) 则有 a+b = c+d (mod p) a-b = c-d(mod p) a*b = c*d (mod p) 所以对于y[i] = i- T[i] ( mod 100 )T[i]为第个人看到所有的其他人的编号之和; 有y[i]-a[i] = i-S(mod 100); (因为a[i] = a[i](mod 100 )); 看右边 如果i取0- 99 则必存在某个特定的i 有i = S(mod p); 因此 i-S(mod 100) = 0; 则y[i]-a[i] (mod 100) = 0; 很显然 y[i] = a[i] (mod 100); 也就是说 只需要让每个人填写的数字为i-T[i] (mod 100)则能够必中一个。 (一)巴什博奕(Bash Game): 只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜. 显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜.因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜.总之,要保持给对手留下(m+1)的倍数,就能最后获胜. 威佐夫博奕(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。 这种情况下是颇为复杂的。我们用(ak,bk)(ak ≤ bk ,k=0,1,2,...,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。前几个奇异局势是:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。 设 (a[k],b[k]) ,a[k]<b[k] ;A[k-1],A[k]-1是离a[k]最近的奇异局势,那么 如果(c[k]=a[k]-a[k-1],d[k] = b[k]-b[k-1]) 是奇异局势那么,a[k],b[k] 肯定不是奇异局势所以a[k],b[k]是个奇异局势 集合问题 现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数。 思路 类似芯片比较问题,采用两两比较的方法,缩小搜索空间。 一个出现了超过1/2的数的性质是: 每次删除最多删除1/2N 个目标数;剩下的数中还是目标数多于1/2N; 任意组成2元组(a,b);最后一个剩下的不做处理保留到下一轮就可以了 如果 a=b 那么随便删除一个; 如果a!=b 那么将两个都删除; 如果只剩下一个那么这个数就是正解。 找明星的问题:明星指所有人都认识他,但是他谁都不认识。在n个人里找明星。 (选两个人 问 甲是否认识乙,认识则甲不是明星,不认识则乙不是明星,收敛速度n/2) 最后找到一个人,那么复杂度为O(n) 寻找中位数 5分法求中位数 5个一组,然后每组的中位数组成新的序列 递归查找。 21根电线杆问题 假设楼下的电线杆编号后进行划分 {1} {2,3} {4,5,6},{7,8,9,10},{11,12,13,14,15},{16,17,18,19,20,21} 也就是6个区间,每个区间数目均不等 将区间内的电线杆用电池串联 上楼顶 两两用灯泡互联 找出 1,2,3,4,5,6 根电线杆的所属区间对应的接口 {a1} {a2,a3} {a4,a5,a6},{a7,a8,a9,a10},{a11,a12,a13,a14,a15},{a16,a17,a18,a19,a20,a21}; 然后进行如此划分 {a1,a2,a4,a7,a11,a16} {a3,a5,a8,a12,a17} {a6,a9,a13,a18} {a10,a14,a19} {a15,a20} {a21} 将区间内的元素用电池串联起来; 到楼下来,很显然,f(a21)可以确定,f(a1)可以确定, 根据{a15 ,a20 } 与{m,n} 关联 则我们确定对应关系即可。 假设通过第一次测试我们发现m属于{11,12,13,14,15} , n属于{16,17,18,19,20,21} 则可以确定f(a15) = m, f(a20) = n 反之同理。 其他的依次类推,找各自对应集合既可以确定所有的对应关系。 网络 OSI(Open System Interconnection,开放系统互连)7层模型: 物理层——网线和接口 数据链路层——数据帧 在不可靠的网络上传输数据 网络层——进行数据的打包,将网络地址翻译成物理地址,进行包的发送,会进行路径选择。 传输层——TCP/IP UDP 将下层数据进行分段传输,使得数据能够满足要求地抵达目的地。 会话层——发起协议://地址:端口号访问请求与应答 建立数据传输通路 表示层——数据解析成图片or 声音 or 视频等 应用层——QQ ftp Internet TCP/IP的3次握手 进程间相互通信方式 用于进程间通讯(IPC)的四种不同技术: 1. 消息传递(管道,FIFO,posix和system v消息队列) 2. 同步(互斥锁,条件变量,读写锁,文件和记录锁,Posix和System V信号灯) 3. 共享内存区(匿名共享内存区,有名Posix共享内存区,有名System V共享内存区) 4. 过程调用 CMMI的分级 1.完成级 小作坊,能够完成一个软件,但无法保证能完成下一个,对人依赖很大。 2.管理级 加入管理成分,有计划和流程的实施项目。 3.定义级 根据标准定义自己的标准和流程,GB GJB, 4.量化管理级 增大管理粒度,量化管理的各个流程,可测量,最后可以定量的评价管理效果。 5.优化级 持续改进 不但可以完成,根据过程的量化反馈,可以优化项目的执行,出现问题后能够及时处理以及改善。 </div>
-
经典面试题搜集
最新推荐文章于 2024-04-08 21:42:39 发布