剑指offer(java)
文章平均质量分 65
水的化合物的专栏
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
剑指offer:第一个只出现一次的字
题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出'b'. 看到这样的题目,我们最直观的想法就是从头开始扫描这个字符串中的字符。当访问某个字符时拿这个字符和后面的每个字符相比较,如果在后面没有发现重复的字符,则该字符就是只出现一次的字符。如果字符串有n个字符,每个字符可能与后面的O(n)个字符想比较,因此这种思路的时间复杂度为O(n2),面试官不会满原创 2016-10-05 21:24:22 · 449 阅读 · 0 评论 -
剑指offer:斐波那契数列(java)
题目一:写一个函数,输入n,求斐波那契数列的第n项。O(N)解法实现: public int getfibN(int n){ if(n == 0){ return 0; }else if(n == 1){ return 1; } int fibNone = 1; i原创 2016-09-29 12:31:29 · 418 阅读 · 0 评论 -
剑指offer:链表中倒数第k个结点(java)
题目: 输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。 一般思路是:先走到链表的尾端,再回溯k步,但由于是单向链表,该思路行不通。另一个思路是,假设链表有n个结点,倒数第k个,就是从头开始第n-k+1个原创 2016-10-02 19:05:22 · 721 阅读 · 0 评论 -
剑指offer:调整数组顺序使奇数位于偶数前面
题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。 如果不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后再数组的末尾有一个空位,这时把该偶数放入这个空位。由于每碰到一个偶数就需要移动O(n)个数字,因此总的时间复杂度是O(n^2原创 2016-10-02 18:43:12 · 674 阅读 · 0 评论 -
剑指offer:反转链表(java)
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。为了正确的反转一个链表,需要调整链表中指针的方向。为了将调整指针这个复杂的过程分析清楚,我们可以借助图形来直观的分析。在图中所示的链表中,h,i,j是3个相邻的结点。假设经过若干的操作,我们已经把结点h之前的指针调整完毕,这些结点的m_pNext都指向前面的一个结点。接下来我们把i的m_pNext指向h,此时原创 2016-10-02 19:33:31 · 461 阅读 · 0 评论 -
剑指offer:合并两个排序的链表(java)
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入图中的链表1和链表2,则合并之后的升序链表3所示。 (a)如果链表1头结点的值小于链表2头结点的值,那么链表1的头结点将是合并后链表的头结点。如果链表2头结点的值小于链表1的头结点的值,那么链表2的头结点将是合并后链表的头结点.(b)我们继续合并两个链表中剩余的结点,由于两个链表剩余结点依然原创 2016-10-02 19:52:05 · 1102 阅读 · 0 评论 -
剑指offer:树的子结构(java)
题目:输入两棵二叉树A和B,判断B是不是A的子结构。例如图中所示的两棵二叉树,由于A中有一部分子树的结构和B 是一样的,因此B是A的子结构。要查找树A中是否存在和树B结构一样的子树,思路是第一步:先在树A中查找与根结点的值一样的结点,这实际就是树的先序遍历,当树A和树B为空时,定义相应的输出。如果树A某一结点的值和树B头结点的值相同,则调用doesTree1HaveTr原创 2016-10-02 20:13:21 · 1233 阅读 · 0 评论 -
剑指offer:二叉树的镜像(java)
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像如图所示:右边的二叉树就是左边的树的镜像上述树求镜像的步骤如下:我们先前序遍历这个树的每个结点,如果遍历到的结点有子结点,就交换它的两个子结点。当交换完所有非叶子结点的左右子结点之后,就得到了树的镜像。public void MirrorRecursively(BinaryTreeNode node){原创 2016-10-02 20:27:22 · 411 阅读 · 0 评论 -
剑指offer:顺时针打印矩阵(java)
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵:1,2,3,45,6,7,89,10,11,1213,14,15,16则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10. 由于是从外圈到内圈的顺序依次打印,我们可以把矩阵想象成若干个圈,如图所示。原创 2016-10-02 23:02:17 · 2404 阅读 · 1 评论 -
剑指offer:包含min函数的栈(java)
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1). 看到这个问题,我们的第一反应可能是每次压入一个新元素进栈时,将栈里的所有元素排序,让最小的元素位于栈顶,这样就能在O(1)时间得到最小元素了。但这种思路不能保证最后压入的元素能够最先出栈,因此这个数据结构已经不是栈了。 我们接着原创 2016-10-03 18:44:43 · 633 阅读 · 0 评论 -
剑指offer:旋转数组的最小数字
题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为旋转。 输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小元素为1.这道题最直观的解法并不难,从头到尾遍历一次,我们就能找到最小的元素。这种思路的时间复杂度为O(n)。但是这个思路没有利用输入的旋转数组的特性,肯定达不到面试官的要求原创 2016-09-29 11:31:32 · 434 阅读 · 0 评论 -
剑指offer:重建二叉树(java)
题目:输入某二叉树的前序遍历和中序遍历的结果,请重新构造出该二叉树。假设输入的前序遍历和中序遍历的结果中不包含重复的数字。例如输入的前序遍历序列为{1,2,4,7,3,5,6,8}和中序遍历为{4,7,2,1,5,3,6,8},则重建出二叉树并输出它的头结点。因为前序遍历:根左右。中序遍历是:左根右。因此前序第一个数字是二叉树的根节点。但在中序中找到根节点的位置,根节点左边是二叉树的左子树,根原创 2016-09-29 10:39:14 · 348 阅读 · 0 评论 -
剑指offer:从尾到头打印链表(java)
一般来说,我们会想到链表逆置,然后再从头打印,但这样会改变链表结构,如果面试官认可的话,则可以,否则还要更简便的方法。1、使用栈 /** * 从尾到头打印链表 * @param root */ public static void printReverseList(ListNode root){ if(root==nu原创 2016-09-29 10:23:02 · 653 阅读 · 0 评论 -
剑指offer:不用加减乘除做加法(java)
题目:写一个函数,求两个整数之和,要求在函数体内不得适用+,-,* ,./ 四则运算符号 面试的时候被问道这个问题,首先我们分析人们是如何进行十进制的加法的,比如如何得出5+17=22这个结果的,实际上,我们可以分三步进行:第一步只做各位相加不进位,此时相加的结果是12,第二步做进位,5+7中有进位,进位的值为10;第三步,把前面的两个结果加起来12+10的结果是22,刚好5+17原创 2016-10-15 15:58:22 · 3280 阅读 · 0 评论 -
剑指offer:求1+2+...+n(c/c++)
题目:求1+2+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句 这个问题本身没有太多的实际意义,但不少面试官认为这是一道不错的考查应聘者发散思维能力的题目,而发散思维能够反映出应聘者知识面的宽度,以及对编程相关技术理解的深度。 求1+2+...+n除了用公式n(1+n)/2之外,无外乎循环和递归两种思路,由于明确限制原创 2016-10-15 15:46:53 · 1023 阅读 · 0 评论 -
剑指offer:圆圈中最后剩下的数字(java)
题目:0,1,,,,,n-1这n 个数字排成一个圆圈,从数字0开始每次从这个圆圈中删除第m个数字。求出这个圆圈里剩下的最后一个数字. 例如,0,1,2,3,4这5个数字组成的一个圆圈,从数字0开始每次删除第3个数字,则删除的前四个数字依次是2,0,4,1因此最后剩下的数字是3. 本题就是著名的约瑟夫环的问题。我们介绍两种方法:一种方法是用环形链表模拟圆圈的经典解法,第二原创 2016-10-15 15:02:10 · 2092 阅读 · 0 评论 -
剑指offer:数值的整数次方(java)
题目描述:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。幂的情况无非是三种:正数、0和负数。当幂是0的时候,直接返回1;当幂是负数的时候,需要先把其转化为正数来处理,然后返回其倒数就可以了,但base为0时,对0求倒数会导致程序运行出错;当幂是正数的时候,按照正常的计算方法就可以。实际上这道题主要考察时代码的健壮性——原创 2016-09-29 13:17:43 · 761 阅读 · 0 评论 -
剑指offer:二进制中1的个数(java)
题目描述:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。比如输入9,9的二进制表示是1001,1的个数是2,所以输出2。这有一个重要结论:一个数与该数减一的结果进行与运算,会把该数右边(低位)第一个1变为0,而该位左边保持不变(高位)。可以举一个简单的例子进行证明:比如1100(对应十进制是12),减去1之后的结果是1011(也就是十进制的11),两个数进行与运算原创 2016-09-29 12:45:49 · 1900 阅读 · 0 评论 -
剑指offer:在O(1)时间删除链表结点(java)
题目描述:给定一个单向链表的头指针和一个结点指针,实现一个函数在o(1)时间删除该结点。 在单向链表中删除一个结点,最常规的做法无疑是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。 那是不是一定需要得到被删除的结点的前一个结点呢?答案是否定的,我们可以很方便得到要删除结点的下一个结点。我们把下一个结点内容复制到要删除的结点上覆盖原有的内容,再把下一原创 2016-09-29 14:20:02 · 884 阅读 · 0 评论 -
剑指offer:打印1到最大的n位数
题目: 输入数字n, 按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1,2,3一直到最大的3位数999.1、这是一个典型的大数加法问题,当面试官不允许使用BigInteger实现大数加法的时候,通常是使用字符串或者数组实现其功能。2、在大数的加法中,我们需要注意的问题是对变量number不断递增+1,实现打印,但我们需要知道什么时候停止number+1,即到了最大的n原创 2016-09-29 14:05:37 · 378 阅读 · 0 评论 -
剑指offer:二维数组中的查找(java)
例如下面的二维数组就是每行、每列都是递增排序。如果在这个数组中查找数字7,则返回true,如果查找数组5,由于数组中不含有该数字,则返回false。1 2 8 92 4 9 124 7 10 136 8 11 15 首先我们选取数组右上角的数字9.由于9大于7,并且9还是第4列的第一个(也是最小的)数字,因此7不可能出现在数字9所在的列原创 2016-09-29 09:42:38 · 542 阅读 · 0 评论 -
剑指offer:替换空格(java)
面试题:替换空格(假设在原来的字符串上替换,并且保证输入的字符串后面有足够多的内存空间)题目:请实现一个函数,把字符串中的每个空格替换成“20%”。例如输入“hellow new world!”,则输出“hellow02%new02%world!”。原因:在网络编程中,如果URL参数中含有特殊字符,如:空格、“#”等,可能导致服务器端无法获得正确的参数值。我们需要将这些原创 2016-09-29 10:06:59 · 1288 阅读 · 0 评论 -
剑指offer:栈的压入、弹出序列(java)
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压栈序列,序列,4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。 解决这个问题很直观的想法就是建立一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列原创 2016-10-03 19:21:19 · 435 阅读 · 0 评论 -
剑指offer:二叉搜索树的后序遍历序列(java)
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。 例如输入数组{5,7,6,9,11,10,8}则返回true,如果输入的数组是{7,4,6,5},由于没有哪颗二叉搜索树的后续遍历的结果是这个序列,因此返回false。 后序遍历得到的序列中,最后一个数字是树的根原创 2016-10-03 20:27:09 · 426 阅读 · 0 评论 -
剑指offer:往上到下打印二叉树(java)
题目:从上往下打印二叉树的每个结点,同一层的结点按照从左到右的顺序打印。例如输入二叉树: 8 / \ 6 10 /\ /\ 5 7 9 11则一次打印出8,6,10,5,7,9 打印过程如下:先打印根结点,为了接下来能够打印8的结点的两个子结点,我们应该在遍历到该结点时把值为6和10的两个结点保存到一个原创 2016-10-03 20:07:34 · 400 阅读 · 0 评论 -
剑指offer:两个链表的第一个公共结点(java)
题目:输入两个链表,找出它们的第一个公共结点。 思路:首先遍历两个链表得到他们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个结点。在第二次遍历的时候,在较长的链表上先走若干步,接着再同时在两个链表上遍历,找到第一个相同的结点就是他们的第一个公共结点。 public ListNode findFirstCommonNode(ListNode root1,ListNode原创 2016-10-05 22:34:16 · 505 阅读 · 0 评论 -
剑指offer:数字在排序数组中出现的次数(java)
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组为{1,2,3,3,,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4 既然输入的数组是排序的,那么我们很自然的想到利用二分查找算法。在题目给出的例子中,我们可以先用二分查找算法找到第一个3.由于3可能出现多次,因此我们找到的3的左右两遍可能都是3,于是我们在找到3的左右两边顺序扫描,分别找出第一个3原创 2016-10-06 10:28:36 · 1196 阅读 · 0 评论 -
剑指offer:二叉树的深度(递归&&非递归)(java)
题目:输入一棵二叉树的根节点,求该数的深度。从根节点到叶结点依次进过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度。例如,如下图的二叉树的深度为4,因为它从根节点到叶结点的最长的路径包含4个结点(从根结点1开始,经过2和结点5,最终到达叶结点7) 如果一棵树只有一个结点,它的深度为1,如果根节点只有左子树而没有右子树,那么树的深度应该是其左子树的原创 2016-10-06 17:35:27 · 2194 阅读 · 0 评论 -
剑指offer:判断二叉树是不是平衡二叉树(java)
题目:输入一棵二叉树的根节点,判断该树是不是平衡的二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。 有了求二叉树的深度的经验之后再解决这个问题,我们很容易就能想到一个思路:在遍历树的每个结点的时候,调用函数TreeDepth得到它的左右子树的深度。如果每个结点的左右子树的深度相差不超过1,按照定义它就是一棵平衡的二叉树。这种思路实现的代码如下:原创 2016-10-06 18:48:19 · 9559 阅读 · 10 评论 -
剑指offer:数组中只出现一次的数字(java)
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请些程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1). 如输入数组{2,4,3,6,3,2,5,5},因为只有4,6这两个数字只出现一次,其他数字都出现了两次,所以输出4,6 这是一个比较难的题目,很少有人在面试的时候不需要提示一下子想到最好的解决办法。一般当应聘者想了几分钟原创 2016-10-06 19:03:31 · 3213 阅读 · 0 评论 -
剑指offer:和为s的两个数字VS和为s的连续正数序列(java)
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多个数字的和等于s,输出任意一对即可。例如输入数组{1,2,4,7,11,15}和数字15.由于4+11=15,因此输出4和11. 只要想到一个办法,应聘者就可以立马告诉面试官,即使这个办法不一定是最好的。比如这个问题,很多人会立即能想到O(n2)的方法,也就是先在数组中固定一个数字,原创 2016-10-06 19:53:16 · 628 阅读 · 0 评论 -
剑指offer:翻转单词顺序VS左旋转字符串(java)
题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串为“I am a Student.",则输出为”Student. a am i". 这个题目是流传甚广,很多公司都多次拿来作为面试题,很多应聘者也多次在各种博客或者书籍上见到过通过两次翻转字符串的解法,于是很快可以跟面试官说出自己的思路:第一步反转句子中所有的原创 2016-10-06 20:41:25 · 713 阅读 · 0 评论 -
剑指offer:n个骰子的点数(java)
题目:把n个骰子仍在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能的值出现的概率。 骰子一共6个面,每个面上都有一个点数,对应的是1-6之间的一个数字。所以n个骰子的点数和的最小值是n,最大值为6n.另外根据排列组合的知识,我们还知道n个骰子的所有点数的排列数为6^n.要解决这个问题,我们需要先统计出每一个点数出现的次数,然后把每一个点数出现的次数除以6^n,就能求出每原创 2016-10-06 22:00:00 · 1838 阅读 · 0 评论 -
剑指offer:扑克牌的顺子(java)
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12,K为13. 思路:随机抽的5张牌可以看成5个数字组成的数组,大、小王是特殊的数字,不妨定义为0.接下来只要判断5个数字是不是连续的。最直观的方法是排序,然后用0去补满数组中的空缺。如果排序后的数组不是连续的,即相邻的两个数字都相隔若干个数字,但只要我们有足够的0可以补原创 2016-10-15 11:36:10 · 2493 阅读 · 0 评论 -
剑指offer:数组中的逆序对(java)
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数例如在数组{7,5,6,4}中,一共存在5对逆序对,分别是{7,6},{7,5},{7,4},{6,4},{5,4}。 看 到这个题目,我们的第一反应就是顺序扫描整个数组。每扫描到一个数组的时候,逐个比较该数字和它后面的数字的大小。如果后面的数原创 2016-10-05 22:29:52 · 8280 阅读 · 2 评论 -
剑指offer:丑数(java)
题目:我们把只包含因子2,3,5的数称为丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做第一个丑数。逐个判断每个整数是不是丑数的解法,直观但不够高效 所谓一个数m是另一个数n的因子,是指n能被m整除,也就是说n%m==0.根据丑数的定义,丑数只能被2,3,5整除。也就是说如果一个数能被2整除,我原创 2016-10-05 19:26:38 · 574 阅读 · 0 评论 -
剑指offer:把数组排成最小的数(java)
题目:输入一个正整数数组,把数组里面所有的数字拼接排成一个数,打印能拼接出的所有数字中的一个。例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323. 这个题目最直接的做法应该是先求出这个数组中的所有数字的全排列,然后把每个排列拼接起来,最后求出排列起来的数字的最小值。求数组的排列和面试题28非常相似。根据排列组合的只是,n个数字总共有n!排列,我们再来原创 2016-10-05 16:44:32 · 1271 阅读 · 0 评论 -
剑指offer:复杂链表的复制(java)
题目:请实现函数ComplexListNode复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL; 下图是一个含有5个结点的该类型复杂链表。图中实线箭头表示m_pNext指针,虚线箭头表示m_pSibling指针。为简单起见,指向NULL的指针没有画出。原创 2016-10-03 21:26:54 · 1096 阅读 · 0 评论 -
剑指offer:二叉树中和为某一值的所有路径(java)
题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶结点所经过的所有的结点形成一条路径。如下图,输入二叉树和整数22,则打印出两条路径,第一条路径包含结点10,12,第二条路径包含的结点为10,5,7. 由于路径是从根结点出发到叶结点,也就是说路径总是以根结点位起始点,因此我们首先需要遍历根结点,也就是按照前原创 2016-10-03 20:39:43 · 2441 阅读 · 0 评论 -
剑指offer:二叉搜索树与双向链表(java)
题目:输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整树中结点指针的指向。比如如下图中的二叉搜索树,则输出转换之后的排序双向链表为: 由于要求转换之后的链表是排好序的,我们可以中序遍历树的每一个结点,这是因为中序遍历算法的特点是按照从小到大的顺序遍历二叉树的每一个结点。当遍历到根结点的时候,我们把树看成三部分:值为10的结点、原创 2016-10-03 22:12:04 · 1392 阅读 · 2 评论
分享