剑指Offer面试编程题
文章平均质量分 67
九度OJ所有的面试题AC并讲解每一道题目的解题思路,网上的代码很多,但解题思路的讲解却很少,而这却恰恰是解题很重要的一环。
huoyao
ZJNU,zz
展开
-
【剑指Offer面试编程题】题目1384:二维数组中的查找--九度OJ
【思路】深入挖掘题目愿意,巧妙利用题目的意图,只需要用要查找的元素与输入的数组每一个元素进行比较即可得到要查找的元素是否在输入的数组里面,数组也不用保存。比较简单的思路,但却是比较巧的解法。AC code:原创 2014-12-04 10:38:44 · 1305 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1510:替换空格--九度OJ
【解题思路】简单题目,逐个输入字符,知道遇到回车停止输入,如中途遇到空格,将空格替换成对应的字符串“%20”输出即可。原创 2014-12-04 12:27:35 · 904 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
【解题思路】这道题目初看了半天,第一反应是怎么会有这么简单的题目,然后也知道了输出的第二列的数有两种情况。case1:输出当前元素的特殊指针值;case2:输出当前元素的特殊指针所指元素的值;写好case1后提交,WA。改用case2情况,提交后AC。思路就是用两vector分别存下元素值和指针值,输出的第二列用指针值为索引从第一行输入中找到对应元素输出即可。原创 2014-12-04 19:29:01 · 962 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1511:从尾到头打印链表--九度OJ
个人感觉这道题目没有什么意思,所以也就懒得用真正的链表去模拟,直接用一个递归输出最后的结果。原创 2014-12-18 20:41:01 · 711 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1385:重建二叉树--九度OJ
结合给出的图片和第一个样例输入来说,从前序输入的第一个元素1在中序输入中的位置可以确定中序输入中1之前的2 4 7三个元素为左子树,同理确定1之后的5 3 8 6四个元素为右子树。 根据以上相同的思路,前序输入中左字数2 4 7的第一个元素2确定为左子树的根元素,在后序输入中确定2之前的元素为左子树的左支,因为2之后没有元素,所以以2为根的树没有右支。同理递归的处理其他元素。最后形成一个完成的树,然后对树递归的进行后序遍历即可得到结果。 题目利用了前序遍历和中序遍历的特点,另外一种情况是给原创 2014-12-18 20:49:09 · 692 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1512:用两个栈实现队列--九度OJ
新建栈st1模拟队列的输入,只要遇到push操作,都将元素压入st1中。另外,新建栈st2模拟队列的输出,如果pop操作时,先判断st1是否为空,当st2为空,则将st1的中的所有元素挨个弹出并压入st2中以备输出,这时的st2中的元素的排列正好是当前所有元素的输入的逆序,符合队列的输出顺序;-->>当出现pop操作时,如果st2不为空,这个时候的栈顶元素真好是当前状态的队列的头元素,则直接弹出栈顶元素作为队列的输出。原创 2014-12-18 21:11:44 · 582 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1386:旋转数组的最小数字--九度OJ
本题可以采用投机取巧的方法来完成,由于所有输入数据都必须要读入,题目的旋转数组的最小元素即可以看做从所有输入元素中寻找最小元素。这样的话,我们可以再输入元素的同时确定最小元素,如果当前输入元素比目标元素小,更新目标元素为当前输入值,继续输入。输入完成后,最小元素的值将保存在目标元素里面。 当然,本题的初衷不是这样的。本题的输入应该是第一个递增序列加上第二递增序列,而最小的元素即第二个递增序列的头元素。所以寻找到第二个递增序列的头元素即可解答该题。第二个递增序列的头元素也很好找,当发现当前输入的元素比之前的原创 2014-12-18 21:28:15 · 1064 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1387:斐波那契数列--九度OJ
本题应该是非常经典的递推/递归问题了,而且递推式子题目也已经给出。由此,可以设置简单的递归函数,其终止条件是调用参数为0或者1的时候。 一点点小技巧:由于题目有多个测试案例,每个案例都需要寻找对应的斐波拉契数。所以在程序的开始可以将所有的斐波拉契数存于一个vector中,后面只需要查询即可。防止最后第70个斐波拉契数较大,采用long数据类型存储。原创 2014-12-18 21:47:09 · 818 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1388:跳台阶--九度OJ
题目从正面突破很难,我们可以换个角度思考,跳上第n个台阶有几种跳法?有两种跳法:从第n-1台阶跳和从第n-2台阶跳。从而,我们自然而然的得到第n个台阶的跳法等于第n-1台阶的跳法+第n-2台阶的跳法。这与斐波拉契数列是不是很像,这样我们很快就能想到万能的递归解法。递归的终止条件是当n==0和n==1时我们能很快知道有几种跳法。原创 2014-12-18 22:19:35 · 738 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1389:变态跳台阶--九度OJ
拿到本题的第一反应就是斐波拉契数列的变种,那么是否可以认为第n台阶的跳法等于前面所有的台阶的跳法相加呢,当然这种想法可以实现,但效率却很低。仔细研读题目,我们就会发现,我们可以去除很多重复的计算。从第1台阶到第n-2台阶的跳法的和其实就等于第n-1台阶的跳法,所以,第n台阶的跳法其实就等于第n-1台阶跳法的两倍。算法的其余部分就不在赘述了,递推式已经出来,而且终止条件也很好计算。原创 2014-12-18 22:36:27 · 626 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1390:矩形覆盖--九度OJ
本题应结合辅助图形来做题,边推导的同时边画图。本题首先需要处理的是,跳出n为偶数的陷阱。因为紧从偶数的角度思考,我们无法建立各数据之间的联系。当从所有的数考虑时,考虑第n个矩形,我们有两种摆放方式:第一种,竖着放,刚好占用第n个矩阵,这样前面n-1个矩形任意摆放,有第n-1个矩形种摆放方式;第二种,横着放,这样,第n-1个矩形也被占用了,所以只有第n-2个矩形种摆放方式。这不正是斐波拉契数列的类型么,而且当n==0 1 2时摆放很容易确定,这也是递推的基础。原创 2014-12-18 22:45:26 · 761 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1513:二进制中1的个数--九度OJ
既然是二进制表示,我们只能从二进制入手,而二进制与位操作是紧密相关的,所以顺水推舟,很容易想多用位操作来实现。既然要统计1的个数,我们可以用一个只有一个1的二进制表示的数与目标数相与,从而就能得到该数1位置对应的目标数二进制位置是否为1,相与的结果为0则给位为0,否则为1。然后依次将数中1位置右移,并与目标数的二进制进行相与即可。原创 2014-12-18 23:12:56 · 664 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1514:数值的整数次方---九度OJ
这个题目初看起来应该是一个比较low的题目,因为这样的需求确实一个函数pow就能完成,而且用累乘的效果也是一样的。所以在题目中直接用pow函数来做了,只需要注意base为0时,如果exponet为负则为一个无穷大的数,要单独处理一下。输出时此采用“%.2ef”的格式就可以满足题目的要求。原创 2014-12-19 20:08:23 · 609 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1515:打印1到最大的N位数--九度OJ
这道题目实在没看出题目的用意,应该是一道比较无语的题目了。首先利用pow函数确定要打印的最大的数,然后依次遍历从1开始打印即可,没有什么技巧。原创 2014-12-19 20:25:35 · 592 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1516:调整数组顺序使奇数位于偶数前面--九度OJ
本题的思路还是比较简单的,对输入的每一个元素都进行判断,若是奇数则直接输出;如是偶数则存入vector中等后续处理。中间只需要对第一个元素的输出格式进行一下特殊处理即可。原创 2014-12-19 20:37:11 · 526 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1517:链表中倒数第k个结点--九度OJ
本题虽然提示要用链表来处理,但只要思路一致,链表也没什么,只不过数据结构稍微复杂一点,但由于我的思路完全体现不出需要用链表的必要性,所以还是什么数据结构都不采用的简洁思想。 先指定第倒数k个元素为k=n-k,不存在则k=-1。然后顺次输入值,若输入到第n-k个元素则记录下该元素,不存在该元素则输出NULL。原创 2014-12-19 20:55:01 · 570 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1518:反转链表--九度OJ
本题正确思路应该是应三个指针p1,p2,p3分别指向相邻的三个元素a,b,c,然后p2->next=p1,p1=p2,p2=p3,p3=p3->next,然后就是继续调整。同时注意对NULL的处理。 但我采用了stl中的list数据结构和其本身具有的reverse函数来完成,因为觉得这种题目要做也可以。原创 2014-12-19 21:14:17 · 729 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1519:合并两个排序的链表--九度OJ
本题应该是非常经典题目了,当然链表数据结构的实现也算是一个考点。主题思路当然将两个链表输入然后,利用两个指针分别指向两个链表表头,一次比较两个指针的值,谁小谁前进,直达有指针到达链表的尾部停止比较。将剩余的值依次链入目标链表中,完成链表的合并。 本题中还是利用了stl中list实现,没有去实现链表的数据结构。效果其他应该是一致的。原创 2014-12-19 21:38:48 · 1049 阅读 · 3 评论 -
【剑指Offer面试编程题】题目1520:树的子结构--九度OJ
一看到树,第一想法就是递归,虽然递归的效率确实不高,但在OJ上讲究时间效率,有时候配合适当的剪枝能快速AC。本题需要两层递归,首先我们要确定A树的哪个子树与B树进行比照,也就是确定A树的子节点,这是第一层递归;另外,在比较的时候我们也需要用到树的递归,对每一个节点进行比较。两层递归的顺序都是树的先序遍历的顺序。 中间有一点点小技巧,在第一层递归时,我们要在确定B树为子树的时候果断停止递归,避免过多的迭代。原创 2014-12-20 19:59:10 · 731 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1521:二叉树的镜像--九度OJ
这道题目的思路应该还是比较清晰的,这里所谓的镜像无非就是树的所有的节点的左右子树对调。要求输出镜像树的先序遍历,我们很容易想到只需要将正常树的前序遍历算法稍作修改即可。只需要将遍历顺序:根-左-右,变为:根-右-左。即可完成任务。 当然前面的数据输入,建树的过程就不做多说了,应该还是比较简单的。中间需要利用set数据结构寻找到根节点的编号,因为根节点不会出现在输入的子节点中,所以也很好找出来。输入:输入可能包含多个测试样例,输入以EOF结束。对于每个测试案例,输入的第一行为一个整数原创 2014-12-20 20:54:01 · 637 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1391:顺时针打印矩阵--九度OJ
这道题目首先给人一种似曾相识的感觉,当完成代码之后发现不对劲,原因就是这次打印的是矩形而不是方阵。所以首先要解决的问题就是当我们在循环的打印每一圈的同时我们怎么保证循环的停止。仔细分析后我们会发现当矩形是m*n时,循环的圈数loop为m、n中较数的一半。且,我们发现若这个较小的数为一个奇数则最后循环打印完成后肯定会剩余一行或者一竖列元素,需要最后单独处理一下。对于每个循环我们维护一个行的最大值hidx和一个列的最大值sidx,便于确定遍历的边界,每次循环从(i,i)元素开始。原创 2014-12-20 21:07:43 · 601 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1522:包含min函数的栈--九度OJ
本题一个最笨的想法就是每次取出所有的栈中的元素然后输出其最小值,然后再从新压入栈,当然这也仅仅是第一反应而已,题目肯定不能这么去解。从最小元素和栈的特点出发,我们每次取的只能是栈顶的元素,那么是不是存在每次取的元素就是我们需要的元素呢,也就是说每次取出的元素都是当前状态下的最小元素。仔细思考一下,我们发现我们可以压栈的时候做文章,我们可以在每次压栈的时候,都压入当前栈状态下的最小元素。 如何做到?若栈为空,但让栈的最小元素就是要压入的元素,直接压入,这个时候我们发现最小元素在栈顶。若栈非空,我们判断原创 2014-12-20 21:52:01 · 546 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1366:栈的压入、弹出序列--九度OJ
本题我们首先想到某个元素出栈意味着它之前的元素肯定都已经入过栈了,而我们发现入栈这一操作具有唯一性,也就是说一个元素只有一次入栈机会(就本题题意而言),那么我们很容易想到我们可以利用一个辅助的数据结构:队列。我们可以将栈的输入序列放入队列中,因为队列的出队具有顺序和唯一性,符合入栈的特点。对于出栈的每一个元素,首先判断栈的栈顶是否为该元素,若是该元素直接出栈即可;若栈顶元素不是该元素,则从队列中出队元素并压入栈,直到队列为空或者在队列中找到该元素为止。 对于出栈顺序中的每一个元素按上述规则处理,若发原创 2014-12-20 22:21:58 · 717 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1523:从上往下打印二叉树--九度OJ
这道题目应该一眼就看看出是树的层序遍历,看出来之后也就没有什么可以说的了。注意首先用数据结构保存树,然后利用set数据结构寻找出根节点。然后就是利用队列进行层序遍历。原创 2014-12-20 22:33:43 · 700 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1367:二叉搜索树的后序遍历序列--九度OJ
对于二叉搜索树我们首先要明确一点:给出二叉搜索树也就意味着给出了的树的中序遍历序列,因为将节点排序后就是中序遍历序列,所以本题目中给出树的后序遍历序列,那么我们就可以唯一的确定一棵树。根据二叉搜索树的特点:树的根节点大于左子树任意元素,小于右节点任意元素,我们可以知道,后序遍历的最后一个节点8即根节点,可以将树分为5 7 6左子树,9 11 10右子树。然后分别对左右子树应用后序遍历的特点继续往下分。 在我们递归分左右子树的过程中需要我们判断序列是否满足二叉树的情况,也即:给定的序列是否满足前面数字原创 2014-12-20 22:51:56 · 874 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1368:二叉树中和为某一值的路径--九度OJ
这道题目的思路应该还是比较清晰的,首先DFS是基础,然后在DFS过程中记录过经过的节点,并注意更新路径的和值,当然也需要动态的维护好经过节点的序列,注意增删,也即访问的时候需要增,当需要往回撤时需要删除节点。最后需要对保存的结果序列排序。原创 2014-12-20 23:27:30 · 1085 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
这道题目主要还是题目的意思有点混淆不清吧,所谓的输出“第二个代表当前节点的特殊指针的值”,很有可能理解成当前节点的指针值,也就是元素的编号。但实际是指针所指的元素的值。题目当然肯定是很简单的,只需要利用两个vector存下元素的值和指针值,然后输出的利用元素的下标即元素的编号也即指针值处理就好。原创 2014-12-22 20:36:06 · 611 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1503:二叉搜索树与双向链表--九度OJ
解题的第一步当然是建树,给出先序遍历的二叉搜索树,自然就可以利用树的先序遍历的特点进行建树。先处理当前节点,再递归处理左支与右支。当遇到0则当前节点为空,退出递归。 第二步则是顺序的调整,顺序的调整当然利用二叉搜索树的中序遍历具有的排序功能,对该树进行中序遍历,且在遍历的时候动态的将节点的左右指针值更改掉。且需要维护一个前节点指针pr,将当期节点的pre指针指向pr,pr的next指针指向当期节点,完成双向链接,然后更新pr为当前节点,继续递归。若当前节点为空则退出递归。 当原创 2014-12-22 21:07:38 · 673 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1369:字符串的排列--九度OJ
由于需要字典序,首先肯定是要先对所给的字符串进行排序,然后很容易想到穷举法,但这边穷举法还有要避免重复,所以,有一定的技巧。我们有三个元素abb,最后输出时三元组,则我们可以将三个位置都看做由所有元素来填充的序列。负责度应该是一个n的n次方,但中间可以有一些剪枝。 由于n的大小不固定,我们没法确定是几层循环,所以只能用递归操作来进行遍历。对每一次递归调用都遍历n个元素哪个适合加入到结果队列res中,同时,我们设置一个used变量来控制某个元素是否已经在res中,避免重复添加。当检测到res的长度原创 2014-12-22 22:00:09 · 711 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1370:数组中出现次数超过一半的数字--九度OJ
这道题目需要注意的一点就是:比较容易和另外一个题目相混淆,另外一个题目是从一堆数中找到出现次数超过一半的那个数,可以利用一次遍历找到。 但本题却是要完成两个任务:确定是否存在那个数+找出那个数。所以本题没法在O(N)的时间复杂度情况下完成,当然本题的解题方法有很多,但都是得好好利用这个出现次数超过一半这一特性。首先必须明确,我们队数组排序后,因为如果存在这个数,则中间元素肯定就是那个要找的值。其中一个解法:首先将数字排序,然后取中间元素值,统计有多少个元素等于中间元素值。若统计的结果比一半小,原创 2014-12-22 22:33:51 · 794 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1371:最小的K个数--九度OJ
本题首先想到的是利用二分查找确定一个元素的位置,然后比较这个位置是在k之前还是之后,若这个位置等于k则停止,否则继续在分开的两个子区间里面确定k位置的元素,直到确定k位置元素后停止。然后对前k个元素排序即可得到前k个有序序列。 但考虑到上面的做法代码比较复杂,且要求通用的话,时间复杂度也挺高。所以决定用一个笨办法试试,直接对所有元素排序,然后取前k个元素输出即可。原创 2014-12-22 22:47:08 · 583 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1372:最大子向量和--九度OJ
这应该是一个非常经典的问题了,看到这种最后化问题,而且各结果之间具有一定的联系的题型,第一反应就是dp问题,因为一个数我们能确定,两个数的话我们可以根据一个数确定,同理第三个数出现后我们能根据前面的数确定。用一个数组记录到当前元素为止的最大和,并记录其起始元素编号。同时寻找最大值。原创 2014-12-22 23:03:39 · 691 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1373:整数中1出现的次数--九度OJ
对于给定一个数,算包含的1的个数,我们可以将这个数分为很多部分,然后分别算1的个数。首先我们很容易得到一个n位数中1的个数,n位数1的个数等于n-1位数中1的个数与10相乘加上第n位为1的额外增加的个数pow(10,n-1)。 例如给定101,可以从第一位开始计算,首先是两位数0-99中1的个数,然后是100 101中首位1的个数,然后到第二位0,不计算。第三位1,计算0位数1个数0个,然后计算1这个数1的个数为1。最后将所有计算结果相加。原创 2014-12-23 20:57:05 · 1194 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1504:把数组排成最小的数--九度OJ
这道题目首先需要看破的一点就是我们需要用字符串来处理,因为当数字拼接是很容易超过机器最大数。另外,我们需要从最简单、最原始的想法出发,来判断数字应该怎么拼接。我们可以想象成对给定的一堆字符串排序,使得最后的排序结果拼接后具有最小值,那么问题就转化为两个字符串谁前谁后的问题。问题已经很明了了,我们可以直接拼接两个字符串a,b成ab和ba。当a放前面拼接后的结果小则a应该放前面,否则b应该放前面。原创 2014-12-23 21:17:52 · 810 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1214:丑数--九度OJ
本题最直观的想法就是从1开始遍历,然后判断每一个数是否为丑数,但这样肯定是一种非常耗时间的做法,不可取。那么我们是否可用从丑数的特点出发呢,从另一个角度来思考问题,我们可以用2 3 5这三个数相乘来组成丑数,我们唯一需要确保的就是我们组成的丑数是按从小到大的关系出现的。我们可以想象一个丑数的出现是前面某一个丑数乘以2 /3 /5的结果,所以我们可以维护三个index,分别对应是2 3 5下一个应该相乘的数,然后依次去这三个数的最小值作为下一个丑数,并更新三个index。如此继续迭代。原创 2014-12-23 21:27:52 · 650 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1283:第一个只出现一次的字符--九度OJ
本题有很多思路可以做,包括map set 排序等应用,但,时间却是个问题。既然提到了字母,我们不妨用最原始的方法,统计每个字母出现的次数,然后按照字母的输入次序遍历26个字母,当某一个字母的次数为1则该字母为所求,否则不存在这样的字母。原创 2014-12-23 23:00:09 · 713 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1348:数组中的逆序对--九度OJ
本题还是有一定的难度的,首先我们不可能通过遍历的方案来完成,时间复杂度过高。然后我们可以想象,是否我们可以通过分块完成,完成字块的统计后,我们使字块有序,然后继续统计其他字块。最后我们合并统计字块。我们融入一种合并排序的思想,通过小块的统计并有序来构造更大的有序块,直到最后全部合并完成。对于两个有序小块之间包含的逆序对,我们只需要判断有限的组合即可完成统计。原创 2014-12-24 19:50:46 · 816 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1505:两个链表的第一个公共结点--九度OJ
本题应该非常经典的题目了,但这种题目我们往往有时候需要注意来输入的不止两个链表的情况,但本题目中已经很清晰的说明了只有两个链表。另外,既然是单链表,就不存在有一个节点具有多个指针指向其他节点。 那么本题还是采用经典的尾部对其的做法,使两个链表尾部对齐后,两个链表同时开始向后扫描,若发现有一个元素值相同则表明两个链表具有相同的节点,后面的节点也就不同扫描了。若扫描完所有的节点都没有找到相同的节点,则表明两个链表不具有共同元素。原创 2014-12-24 20:50:41 · 768 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1349:数字在排序数组中出现的次数--九度OJ
本题很容易想到用map和set数据结构来完成。但map的构建和最后对map的查询需要的时间代价很大,但空间和时间应该是不允许的。综合查询操作和数组的有序的特点,我们采用二分查找来确定元素是否在数组里面。若在数组里面,则将其周围的元素的个数统计完成后输出。原创 2014-12-24 21:01:56 · 1016 阅读 · 0 评论 -
【剑指Offer面试编程题】题目1352:和为S的两个数字--九度OJ
本题是求和,我们首先可以考虑第一个元素该与哪个元素搭配,当然应该是最大的最后一个元素。对于这两个元素的和若与给定元素比较相等,当然是最好,直接输出。若比较后结果偏大,怎么调?当然只能是后面的那个元素前移;相对应的若偏小,则当然是前面的元素后移。最后我们能得到一个通过调整后相等的结果,若所有元素组合后没有满足条件,我们则认为数组没有和满足的组合。 那么这种思路为什么一定能找到呢?我们可以想象和为s的组合是其中的某一组,我们一定可以通过这种两端压缩的方式进行,原因是这种压缩的调整策略是一定的而且是合原创 2014-12-24 21:09:24 · 825 阅读 · 0 评论