《剑指Offer》Java版
文章平均质量分 62
《剑指Offer》书中全部50道题目的Java实现,详见目录。
login_sonata
这个作者很懒,什么都没留下…
展开
-
《剑指Offer》Java版目录(源码下载)
《剑指Offer》PDF版下载:点我书中全部50道题目的Java实现如下,java源码下载:点我剑指Offer面试题1面试题2单例模式 剑指Offer面试题3二维数组查找 剑指Offer面试题4替换空格 剑指Offer面试题5反向打印链表 剑指Offer面试题6重建二叉树(根据前序中序输出后序) 剑指Offer面试题7用两个栈实现队列(附带用两个队列实现栈) 剑指Offer面试题8旋转数原创 2017-08-18 10:37:27 · 4232 阅读 · 3 评论 -
剑指Offer面试题1面试题2单例模式
面试题1:赋值运算符函数java只能重载“+”和“+=”两个运算符,别的都不可以。面试题2:单例模式。单例模式有以下特点:1,单例类只能有一个实例。2,单例类必须自己创建自己的唯一实例。3,单例类必须给所有其它对象提供这一实例。总之,选择单例模式为了避免不一致状态,如打印机。写法1:饿汉式//在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以原创 2017-02-22 16:00:34 · 1561 阅读 · 0 评论 -
剑指Offer面试题3二维数组查找
面试题3:二维数组查找在一个二维数组中,每一行的数从左到右递增,每一列的数从上到下递增。输入这样的一个数组和一个整数,判断数组中是否含有该整数。思路:别从左到右一个一个比,先比右上角的或左下角的,如果要找的数比这个数小,剔除这一列,比较前一列的第一个数。如果大,剔除这一行,再比较该列下一个数。注意如果先比左上角或右下角的是不行的。import java.util.Scanner;原创 2017-02-22 16:03:30 · 882 阅读 · 0 评论 -
剑指Offer面试题4替换空格
面试题4,替换空格,把字符串中的空格替换为%20。思路1:用另一个String进行复制或者替换比较方便。思路2:先统计空格数量,确定扩长后的String总长度,一个指针a在原始字符串末尾,一个指针b在扩长后的字符串末尾。向前移动a,把字符复制给b,直到遇到空格。思路3:遇到空格就后移字符,这是不好的方法,复杂度n*n。所以如果合并字符串或者数组时从前往后复制需要移动字符多次,那么就考虑原创 2017-02-22 16:10:01 · 737 阅读 · 0 评论 -
剑指Offer面试题5反向打印链表
面试题5:反向打印链表。输入一个链表的头结点,从尾到头打印每个节点的值(打印操作一般不改变链表的结构)。思路1:典型的后进先出,用栈。思路2:能用栈就能用递归(层数太深容易溢出),访问到一个节点后,递归输出它后面的节点,再输出该节点自身。提供了java和c的两种实现。先看java的:public class PrintListReversingly { //尾插法建立链表原创 2017-02-26 13:15:17 · 1480 阅读 · 0 评论 -
剑指Offer面试题6重建二叉树(根据前序中序输出后序)
面试题6:重建二叉树。输入二叉树的前序遍历和中序遍历结果,重建二叉树。假设输入的前序和中序结果都不含重复的数,例如:前序12473568,中序47215386,输出后序遍历结果。思路:所谓前中后序即根节点的访问顺序。前序的第一个数肯定是根节点,而根节点在中序里的中间位置,其左为左子树,右边是右子树。假设中序的根节点左边有3个数,可知根节点的左子树有3个节点,此时这三个数的顺序即是左子树原创 2017-02-26 15:49:01 · 2159 阅读 · 0 评论 -
剑指Offer面试题7用两个栈实现队列(附带用两个队列实现栈)
面试题7:用两个栈实现队列完成两个函数appendTail和deletedHead,分别是在队列尾部插入节点和在队列头部删除节点的功能。思路:添加元素即压入一个栈s1,删除元素的话,把s1中的元素按顺序先弹出再压入栈s2中,这是弹出栈s2的元素就能实现先进先出了。相关题:用两个队列实现栈。思路:添加元素即向一个队列q1添加元素,删除元素的话,把q1的元素按顺序出队然后入队到q2,最原创 2017-03-02 18:05:34 · 704 阅读 · 0 评论 -
剑指Offer面试题8旋转数组的最小数字(二分查找)附带快排和按年龄排序
面试题8:旋转数组的最小数字把一个数组最开始的几个元素搬到数组末尾,我们称之为数组的旋转,输入一个递增的数组的旋转,输出它的最小元素。如{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,输出1。思路:直观想法是从头到尾遍历就行,复杂度O(n),但是这个数组其实已经划分为两个排好序的子数组,前面一个子数组的元素都大于等于后边一个,并以最小元素为分界。对于排好序的数组,推荐用二分查原创 2017-03-02 18:11:07 · 731 阅读 · 0 评论 -
剑指Offer面试题9斐波那契数列
面试题9:斐波那契数列写一个函数,输入n,求斐波那契数列的第n项。斐波那契数列定义如下:n=0时,f(n)=0;n=1时,f(n)=1;n>1时,f(n)=f(n-1)+f(n-2)思路1:先判断n比如求f(10),要先求f(9)和f(8),以此类推,如果把f(10)作为二叉树的根节点,那么整个树的节点会有很多重复的,复杂度随n的增加而指数增加。思路2:更简单的办法不是从n开始往下原创 2017-03-04 20:35:30 · 770 阅读 · 0 评论 -
剑指Offer面试题10二进制中1的个数(位运算)附带一个进制转换题
面试题10:二进制中1的个数实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如9的二进制是1001,则输出2。位运算相关知识:位运算共5种,与(&)是同时为1才为1,或(|)是有一个为1就是1,异或(^)是不相同为1。左移运算符m右移运算符m>>n表示m右移n位,最右边n位丢弃,注意,如果数字是一个无符号数值,则用0填补最左边的n位。如果是有符号数值,如正,左边补n个0原创 2017-03-04 20:42:15 · 1729 阅读 · 0 评论 -
剑指Offer面试题11数值的整数次方
面试题11:数值的整数次方实现函数double Power(double base,int exponent),求base的exponent次方,不得使用库函数,不用考虑大数问题。注意:判断两个小数是否相等不能用==,因为计算机表示小数有误差,我们只能判断它们差的绝对值是否在一个很小的范围内。题外话:程序错误处理的三种方法:返回值、全局变量、异常。返回值好处是根据返回值判断错误原因,缺原创 2017-03-05 00:14:19 · 726 阅读 · 0 评论 -
剑指Offer面试题12打印1到最大的n位数,面试题13在O(1)时间删除链表结点
面试题12:打印1到最大的n位数输入数字n,按顺序打印出从1最大的n位十进制数。例如输入3,则打印出1,2,3,...,一直到最大的3位数即999。注意:没有限定n的范围时,注意大数问题,n可能会超出基本数值类型的表示范围,此时可以用字符串来表示,每一位上都是0-9的遍历,可以用递归。题外话:Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,理论原创 2017-03-05 19:31:25 · 665 阅读 · 0 评论 -
剑指Offer面试题14使数组中的奇数在偶数前,面试题15链表倒数第k个结点
面试题14:使数组中奇数位于偶数前输入一个整数数组,实现一个函数来调整数组中的数字的顺序,使得所有奇数位于数组的前半部分,偶数位于后半部分。思路:前后各一个指针相互靠近,如果前偶后奇,交换位置,直到两个指针相遇。复杂度O(n)。注意:如果题目换成负数在正数前边,或能被3整除的在不能的前边等,只是判断条件改变,所以我们把判断功能分离出来,每次只修改这个功能就行了。本题Java实现:原创 2017-03-07 23:03:33 · 734 阅读 · 0 评论 -
剑指Offer面试题16反转链表(递归和非递归),面试题17合并两个排序的链表(递归)
面试题16:反转链表(递归和非递归)输入一个链表的头结点,反转该链表并输出反转后链表的头结点。思路1:定义三个指针,分别是当前要反转的结点,它的前一个结点和后一个结点。思路2:用递归。先找到倒数后两个结点反转,依次向前。以下是本题Java实现:class ListNode{ int value; ListNode next; public ListNode(int x)原创 2017-03-10 17:11:35 · 785 阅读 · 0 评论 -
剑指Offer面试题18树的子结构(递归),面试题19二叉树的镜像(递归和非递归用栈)
面试题18:树的子结构(递归)判断二叉树B是不是二叉树A的子树.思路:两步:1,递归调用hasSubtree先遍历A中有没有结点的值和B的根结点相同,如果有,调用doesTree1HaveTree2做第二步判断。2,判断AB结构是否相同,即递归判断左右结点。本题Java实现:public class DoesTree1HaveTree2 { private boolean dos原创 2017-03-14 10:10:51 · 879 阅读 · 0 评论 -
剑指Offer面试题20顺时针打印矩阵,面试题21包含min函数的栈
面试题20:顺时针打印矩阵思路:一圈一圈打印,再具体到四个边分别打印。本题的Java实现:public class PrintMatrixInCircle { public void PrintMatrixClockwisely(int[][] a){ if (a==null) return; int rows=a.length;原创 2017-03-14 10:40:42 · 581 阅读 · 0 评论 -
剑指Offer面试题22栈的压入弹出序列,面试题23从上到下打印二叉树(层序遍历用队列)
面试题22:栈的压入弹出序列输入两个整数序列,第一个序列表示压入顺序,判断第二个序列是否为弹出顺序.假设入栈所有数字均不相等。思路:构建辅助栈,以压入序列1、2、3、4、5,弹出序列4、5、3、2、1为例,第一个弹出的是4,所以要先把4压入栈,此时栈里有1234,弹出栈顶即可,下一个弹出5,就依次压入直到5,弹出。再举个反例,以弹出序列4、3、5、1、2为例,首先栈里有1234了,下一原创 2017-03-14 10:43:54 · 750 阅读 · 0 评论 -
剑指Offer面试题24二叉搜索树的后序遍历序列(递归),面试题25二叉树中和为某一值的路径(栈)
面试题24:二叉搜索树的后序遍历序列(递归)输入一个数组,判断数组是不是二叉搜索树的后序遍历结果。思路:注意是搜索树,即左孩子相关题目:后序变成前序也是这个思路,树的遍历关键都是先找根结点。本题Java实现如下:public class VerifySequenceOfBST { private boolean verifySequenceOfBST(int[] arr){原创 2017-03-14 10:50:54 · 658 阅读 · 0 评论 -
剑指Offer面试题26复杂链表的复制,面试题27二叉搜索树和双向链表(递归)
面试题26:复杂链表的复制复制一个复杂链表,这个链表除了next指针,还有指向任意一个结点的sibling指针或空指针。思路1:一个效率很低的方法:分两步,先复制一遍next链表,然后设置sibling指针。但由于不知道它指向的位置,所以要遍历一遍链表(在原链表中,从头走了几步,在新链表中,也走几步,这就能确定位置了),这样每个结点设置sibling都要经过O(n)步,总复杂度O(n^2)原创 2017-03-14 10:57:47 · 649 阅读 · 0 评论 -
剑指Offer面试题28字符串的排列组合(递归和栈)
面试题28:字符串的全排列(递归)输入一个字符串,打印出字符串中字符的所有排列,例如输入abc,输出abc,acb,bac,bca,cab,cba。思路:把一个字符串看成两个部分,第一部分是它的第一个字符,第二部分是它后边的所有字符。求所有排列的过程可看做两步,第一步求所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符交换。第二步固定第一个字符,求后面所有字符的排列,此时仍原创 2017-04-30 10:56:13 · 2920 阅读 · 0 评论 -
剑指Offer面试题29数组中出现次数超过一半的数字(涉及快排)
面试题29:数组中出现次数超过一半的数字(涉及快排)数组中有一个数字出现的次数超过数组长度的一半,输出这个数字。思路1:先用快排把数组排好序,然后中间的那个数就是出现次数最多的,快排复杂度为O(nlogn)。但实际中,我们不用一次性完成快排,只需快排一轮后检查我们选择的快排的key所在的下标是不是数组中间数就行了。总复杂度O(n),这种方法会修改数组,因此要看是否允许这样做,快排是不稳定的原创 2017-04-30 11:06:49 · 873 阅读 · 0 评论 -
剑指Offer面试题30最小的K个数(涉及堆或快排)
面试题30:最小的K个数(涉及快排与堆)输入n个整数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。最简单的方法是先排序再输出,复杂度为O(nlogn),但还有更快的方法。思路1:类似面试题29,也用快排的思想。快排一轮后检查我们选择的快排的key所在的下标是不是k-1就行了(不一定是排序的)。复杂度为O(n),但是要修改数组。原创 2017-04-30 11:30:13 · 1287 阅读 · 0 评论 -
剑指Offer面试题31连续子数组的最大和,面试题32从1到n整数中1出现的次数
面试题31:连续子数组的最大和输入一个整数型数组,有正有负,数组中的一个或多个数字组成子数组,求所有子数组的和的最大值,要求时间复杂度为O(n)。 例如输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为该子数组的和18。 思路:从头到尾逐个累加数组中的数字作为当前和,初始化为0,如果当前和小于等于0,那么和下一个要累加的数相加后肯定比这原创 2017-05-29 16:24:06 · 908 阅读 · 0 评论 -
剑指Offer面试题33把数组排成最小的数,面试题34丑数
面试题33:把数组排成最小的数输入一个正整数数组,把数组中所有的数拼接起来组成一个数,输出最小的。比如输入{3,32,321},输出321323。 思路1:全排列,类似面试题28,n个数共有n!个排列,复杂度比较高。 思路2:重写一种比较大小的方法,详见代码。 Java实现如下:import java.util.Arrays;import java.util.Comparator;publi原创 2017-07-02 18:02:41 · 646 阅读 · 0 评论 -
剑指Offer面试题35第一个只出现一次的字符,面试题36数组中的逆序对
面试题35:第一个只出现一次的字符例如输入“abaccdeff”,输出b。 思路:从头到尾挨个扫描肯定是不行的,复杂度O(n^2)太高了。所以用哈希,空间换时间。 相关题目1:输入两个字符串,从第一个字符串中删除在第二个字符串中出现过的字符。可以用哈希来存储第二个字符串中的字符,然后扫描第一个字符串,用O(1)的时间就能判断字符在不在第二个字符串里,总时间复杂度O(n)。 相关题目2:删除字符原创 2017-07-16 15:53:10 · 719 阅读 · 0 评论 -
剑指Offer面试题37两个链表的第一个公共结点,面试题38数字在排序数组中出现的次数
面试题37:两个链表的第一个公共结点输入两个单向链表,输出公共节点。注意了,两个单链表如果有公共节点,形状肯定是Y型的,因为每个结点都只有一个next结点,这个公共节点之后不会有分支了。 思路:假如链表长度分别为m和n,采用固定一个链表的第一个结点,遍历另一个链表的方法的复杂度为O(m*n),有点大了,所以换个思路,既然公共节点之后的结点都是共有的,两个链表的长度差别只在公共节点之前,所以可以先得原创 2017-07-22 19:18:16 · 522 阅读 · 0 评论 -
剑指Offer面试题39二叉树的深度(以及判断平衡二叉树),面试题40数组中只出现一次的数字
面试题39:二叉树的深度(以及判断平衡二叉树)思路:二叉树的深度可以用递归去求,首先如果只有根节点,深度为1,如果根节点只有一个子树,深度为子树的深度+1,如果有两个子树,深度为两个子树的深度较大值加+1。 至于判断平衡二叉树的思路:有了上边求深度的方法后,马上可以想到去遍历树节点,对其子树调用求深度的函数,如果每个结点的左右子树的深度相差都不超过1,就是平衡二叉树。但是这种方法会重复遍历结点,效原创 2017-07-23 17:36:28 · 792 阅读 · 1 评论 -
剑指Offer面试题41和为s的两个数字与和为s的连续正数序列,面试题42翻转单词顺序与左旋转字符串
面试题41:和为s的两个数字,和为s的连续正数序列问题1:输入一个递增排序的数组和一个数字s.在数组中查找两个数使他们的和为s,如果有多对数字的和等于s,输出任意一对即可。 思路:固定一个数字然后遍历其它数字的复杂度O(n^2)的方法肯定不好,注意这是递增的数组,可以2个指针分别指向开头末尾,即最小最大的数,然后判断和是否等于s,若小于s,则前边的指针后移,若大于s,后边的指针前移。一个循环即可复原创 2017-07-30 15:21:57 · 948 阅读 · 0 评论 -
剑指Offer面试题43n个骰子的点数(动态规划),面试题44扑克牌的顺子
面试题43:n个骰子的点数(动态规划)扔n个骰子,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能的值出现的概率。 思路:n个骰子和最小为你,最大为6n,根据排列组合,n个骰子的所有点数的排列为6^n,我们需要先统计出每一种点数和的出现次数,然后除以6^n即为概率。动态规划分析如下: 当有n个骰子,点数和为s,则每一种点数和出现的次数记为f(n,s)。现在假设我有n-1个骰子,再增加一原创 2017-07-30 19:56:33 · 959 阅读 · 0 评论 -
剑指Offer面试题45圆圈中最后剩下的数字(约瑟夫环问题),面试题46求1+2+...+n
面试题45:圆圈中最后剩下的数字(约瑟夫环问题)0,1…n-1这n个数字排成一个圆圈,从第一个人开始报数,数到m的人出局,然后从下一个人开始报数,求这个圈圈里剩下的最后一个数字。 思路:可用ArrayList模拟链表弄出一个圈,删到最后就剩一个数时输出,详见程序。 Java实现如下:public class LastRemaining { static int lastRemaining原创 2017-08-13 14:42:50 · 867 阅读 · 0 评论 -
剑指Offer面试题47不用加减乘除做加法(位运算),面试题48不能被继承的类(final)
面试题47:不用加减乘除做加法思路:用位运算分三步,第一步不考虑进位对每一位相加(结果就是做异或的结果);第二步记下进位,只有1+1会产生进位(等于先做与运算再左移一位);第三步更新两个数分别为异或的结果和与的结果,重复前面两步直到不产生进位。 相关问题:不使用新变量交换两个变量的值 基于加减法: a = a + b; b = a - b; a = a - b; 基于异或: a = a原创 2017-08-13 15:02:19 · 611 阅读 · 0 评论 -
剑指Offer面试题49字符串转整数,面试题50二叉树两个结点的最低公共祖先
面试题49:字符串转整数这里的整数是指int,要考虑的问题如下: 1,输入null或空串; 2,正负号; 3,非法字符; 4,int越界(所以返回类型定义为long)。 Java实现如下:public class StrToInt { public static long str2int(String str) throws Exception{ if(str ==原创 2017-08-17 18:50:14 · 774 阅读 · 0 评论