程序员面试题精选329.docx
《程序员面试题精选329.docx》由会员分享,可在线阅读,更多相关《程序员面试题精选329.docx(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、程序员面面试题精精选1000题(10)在排排序数组组中查找找和为给给定值的的两个数数字数组20007-03-14 15:25:01阅阅读46663评评论155字字号:大大中小订阅题目:输输入一个个已经按按升序排排序过的的数组和和一个数数字,在在数组中中查找两两个数,使使得它们们的和正正好是输输入的那那个数字字。要求求时间复复杂度是是O(nn)。如如果有多多对数字字的和等等于输入入的数字字,输出出任意一一对即可可。例如输入入数组11、2、4、7、11、15和数数字155。由于于4+111=115,因因此输出出4和11。分析:如如果我们们不考虑虑时间复复杂度,最最简单想想法的莫莫过去先先在数组组中
2、固定定一个数数字,再再依次判判断数组组中剩下下的n-1个数数字与它它的和是是不是等等于输入入的数字字。可惜惜这种思思路需要要的时间间复杂度度是O(n2)。我们假设设现在随随便在数数组中找找到两个个数。如如果它们们的和等等于输入入的数字字,那太太好了,我我们找到到了要找找的两个个数字;如果小小于输入入的数字字呢?我我们希望望两个数数字的和和再大一一点。由由于数组组已经排排好序了了,我们们是不是是可以把把较小的的数字的的往后面面移动一一个数字字?因为为排在后后面的数数字要大大一些,那那么两个个数字的的和也要要大一些些,就有有可能等等于输入入的数字字了;同同样,当当两个数数字的和和大于输输入的数数字
3、的时时候,我我们把较较大的数数字往前前移动,因因为排在在数组前前面的数数字要小小一些,它它们的和和就有可可能等于于输入的的数字了了。我们把前前面的思思路整理理一下:最初我我们找到到数组的的第一个个数字和和最后一一个数字字。当两两个数字字的和大大于输入入的数字字时,把把较大的的数字往往前移动动;当两两个数字字的和小小于数字字时,把把较小的的数字往往后移动动;当相相等时,打打完收工工。这样样扫描的的顺序是是从数组组的两端端向数组组的中间间扫描。问题是这这样的思思路是不不是正确确的呢?这需要要严格的的数学证证明。感感兴趣的的读者可可以自行行证明一一下。参考代码码:/ Fiind twoo nuumb
4、eers witth aa suum iin aa soorteed aarraay/ Ouutpuut: turre iis ffounnd ssuchh twwo nnumbberss, ootheerwiise fallse/boool FinndTwwoNuumbeersWWithhSumm(intt daata, / a sorrtedd arrrayyunssignnediint lenngthh, / thee leengtth oof tthe sorrtedd arrrayy intt suum, / thhe ssumiint& nuum1, / thee fiirstt
5、nuumbeer, outtputtintt& nnum22 / thhe ssecoond nummberr, ooutpput)booll fooundd = fallse;if(llenggth bbehiind)lonng llongg cuurSuum = daataaheead + dattabbehiind;/ if thee suum oof ttwo nummberrs iis eequaal tto tthe inpput/ wwe hhavee fooundd thhemiif(ccurSSum = summ)numm1 = daatabehhindd;numm2 = d
6、aataaheead;fouund = ttruee;breeak;/ if thee suum oof ttwo nummberrs iis ggreaaterr thhan thee innputt/ deccreaase thee grreatter nummberrelsseiff(cuurSuum suum)aheead -;/ if thee suum oof ttwo nummberrs iis llesss thhan thee innputt/ inccreaase thee leess nummberrelssebehhindd +;retturnn fooundd;扩展:
7、如如果输入入的数组组是没有有排序的的,但知知道里面面数字的的范围,其其他条件件不变,如如何在OO(n)时间里里找到这这两个数数字程序员面面试题精精选1000题(11)求二二元查找找树的镜镜像树 20007-03-15 09:36:33 阅读339066 评论论9 字号号:大中中小订订阅题目:输输入一颗颗二元查查找树,将将该树转转换为它它的镜像像,即在在转换后后的二元元查找树树中,左左子树的的结点都都大于右右子树的的结点。用用递归和和循环两两种方法法完成树树的镜像像转换。例如输入入: 8 / 6 100/ /5 7 99 11输出: 88 / 100 6/ /111 99 77 55定义二元元查
8、找树树的结点点为:struuct BSTTreeeNodde / aa noode in thee biinarry ssearrch treee (BSTT)intt m_nVaaluee; / vvaluue oof nnodeeBSTTreeeNodde *m_pLeeft; / lleftt chhildd off noodeBSTTreeeNodde *m_pRiightt; / rrighht cchilld oof nnodee;分析:尽尽管我们们可能一一下子不不能理解解镜像是是什么意意思,但但上面的的例子给给我们的的直观感感觉,就就是交换换结点的的左右子子树。我我们试着着在遍历
9、历例子中中的二元元查找树树的同时时来交换换每个结结点的左左右子树树。遍历历时首先先访问头头结点88,我们们交换它它的左右右子树得得到: 88 / 10 6/ /9 11 5 7我们发现现两个结结点6和10的左左右子树树仍然是是左结点点的值小小于右结结点的值值,我们们再试着着交换他他们的左左右子树树,得到到: 88 / 100 6/ /111 99 77 5刚好就是是要求的的输出。上面的分分析印证证了我们们的直觉觉:在遍遍历二元元查找树树时每访访问到一一个结点点,交换换它的左左右子树树。这种种思路用用递归不不难实现现,将遍遍历二元元查找树树的代码码稍作修修改就可可以了。参参考代码码如下:/ Mi
10、irroor aa BSST (swaap tthe lefft rrighht cchilld oof eeachh noode) reecurrsivvelyy/ thee heead of BSTT inn innitiial calll/voiid MMirrrorRRecuursiivelly(BBSTrreeNNodee *ppNodde)if(!pNoode)retturnn;/ swaap tthe rigght andd leeft chiild subb-trreeBSTTreeeNodde *pTeemp = ppNodde-m_ppLefft;pNoode-m_pLee
11、ft = ppNodde-m_ppRigght;pNoode-m_pRiightt = pTeemp;/ mirrrorr leeft chiild subb-trree if nott nuulliif(ppNodde-m_ppLefft)MirrrorrReccurssiveely(pNoode-m_pLeeft); / mirrrorr riightt chhildd suub-ttreee iff noot nnulllif(ppNodde-m_ppRigght)MirrrorrReccurssiveely(pNoode-m_pRiightt); 由于递归归的本质质是编译译器生成成了一
12、个个函数调调用的栈栈,因此此用循环环来完成成同样任任务时最最简单的的办法就就是用一一个辅助助栈来模模拟递归归。首先先我们把把树的头头结点放放入栈中中。在循循环中,只只要栈不不为空,弹弹出栈的的栈顶结结点,交交换它的的左右子子树。如如果它有有左子树树,把它它的左子子树压入入栈中;如果它它有右子子树,把把它的右右子树压压入栈中中。这样样在下次次循环中中就能交交换它儿儿子结点点的左右右子树了了。参考考代码如如下:/ Miirroor aa BSST (swaap tthe lefft rrighht cchilld oof eeachh noode) Itteraativvelyy/ Inpput:
13、 pTTreeeHeaad: thee heead of BSTT/vvoidd MiirroorItteraativvelyy(BSSTreeeNoode *pTTreeeHeaad)if(!pTrreeHHeadd)retturnn;stdd:sstaccksstacckTrreeNNodee;staackTTreeeNodde.ppushh(pTTreeeHeaad);whiile(staackTTreeeNodde.ssizee()BSTTreeeNodde *pNoode = sstacckTrreeNNodee.toop();staackTTreeeNodde.ppop();/ s
14、waap tthe rigght andd leeft chiild subb-trreeBSTTreeeNodde *pTeemp = ppNodde-m_ppLefft;pNoode-m_pLeeft = ppNodde-m_ppRigght;pNoode-m_pRiightt = pTeemp;/ pussh lleftt chhildd suub-ttreee innto staack if nott nuulliif(ppNodde-m_ppLefft)staackTTreeeNodde.ppushh(pNNodee-mm_pLLeftt);/ pussh rrighht cchil
15、ld ssub-treee iintoo sttackk iff noot nnulllif(ppNodde-m_ppRigght)staackTTreeeNodde.ppushh(pNNodee-mm_pRRighht);程序员面面试题精精选1000题(12)从上上往下遍遍历二元元树队列 220077-033-199 211:177:033 阅读读37998 评评论5 字字号:大大中小订阅题目:输入一一颗二元元树,从从上往下下按层打打印树的的每个结结点,同同一层中中按照从从左往右右的顺序序打印。例如输入入 88 / 66 100 / / 5 7 9 111输出8 66 10 55 7 9 1
16、11。分析:这这曾是微微软的一一道面试试题。这这道题实实质上是是要求遍遍历一棵棵二元树树,只不不过不是是我们熟熟悉的前前序、中中序或者者后序遍遍历。我们从树树的根结结点开始始分析。自自然先应应该打印印根结点点8,同时时为了下下次能够够打印88的两个个子结点点,我们们应该在在遍历到到8时把子子结点66和10保存存到一个个数据容容器中。现现在数据据容器中中就有两两个元素素6和10了。按按照从左左往右的的要求,我我们先取取出6访问。打打印6的同时时要把66的两个个子结点点5和7放入数数据容器器中,此此时数据据容器中中有三个个元素110、5和7。接下下来我们们应该从从数据容容器中取取出结点点10访问问
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序员 试题 精选 329
限制150内