剑指offer第二版(java)
本专栏精选自谷歌、微软等知名IT企业的60余道典型面试题,系统地总结了如何在面试时写出高质量代码,如何优化代码效率,以及分析、解决难题的常用方法。
许文杰
Java程序开发
展开
-
剑指offer第二版面试题48:最长不含重复字符的子字符串(java)
题目描述: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符串中只包含从’a’到’z’的字符。例如,在字符串中”arabcacfr”,最长非重复子字符串为”acfr”,长度为4。分析思路: 使用动态规划,记录当前字符之前的最长非重复子字符串长度f(i-1),其中i为当前字符的位置。每次遍历当前字符时,分两种情况:1)若当前字符第一次出现,则最长非重...原创 2018-07-10 09:40:12 · 915 阅读 · 6 评论 -
剑指offer第二版面试题47:礼物的最大价值(java)
题目描述: 在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?分析思路: 利用循环的动态规划实现,使用辅助二维数组 •定义f(i,j)表示到达坐标为(i,j)的格子时能拿到的礼物总和的最大值; •有两种路...原创 2018-07-09 09:59:08 · 1522 阅读 · 0 评论 -
剑指offer第二版面试题46:把数字翻译成字符串(java)
题目描述: 给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”…25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。分析思路: 用递归自顶向下分析,用动态规划自低向上求解 •定义问题:当最开始的一个或者两个数字被翻译成一个字符后,我们接着翻译...原创 2018-07-09 09:22:22 · 993 阅读 · 5 评论 -
剑指offer第二版面试题45:把数组排成最小的数(java)
题目描述: 输入一个正整数数组,把数组里面所有的数字拼接排成一个数,打印能拼接出的所有数字中的一个。例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323。分析实例: 这个题目最直接的做法应该是先求出这个数组中的所有数字的全排列,然后把每个排列拼接起来,最后求出排列起来的数字的最小值。求数组的排列和面试题28非常相似。根据排列组合的只是,n个数字总共有n!排列,我...原创 2018-07-09 09:04:50 · 429 阅读 · 2 评论 -
剑指offer第二版面试题44:数字序列中某一位的数字(java)
题目描述: 数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。分析思路: 寻找数学规律 跳过不同位数的数字,在相应位数中寻找 •以序列中第1001位为例: •序列前10位为0-9,跳过,再从后面找991位; •后面180位为10-9...原创 2018-07-09 08:35:46 · 698 阅读 · 0 评论 -
剑指offer第二版面试题43:1~n整数中1出现的次数(java)
题目描述: 输入一个整数n,求从1到n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,和12。一共出现了5次。分析思路1:不考虑时间效率的解法,靠它想拿offer有点难 如果在面试的时候碰到这个问题,应聘者大多能想到最直观的方法,也就是累加1到n中每个整数1出现的次数。我们可疑每次通过对10求余数判断整数的个位数字是不是1。如果这个数字大于...原创 2018-07-07 12:17:53 · 754 阅读 · 1 评论 -
剑指offer第二版面试题42:连续子数组的最大和(java)
题目描述: 输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为该子数组的和18。分析思路: Step1.从头到尾逐个累加数组中的每个数字,初始化和为0;(nCurrSum=0,nGre...原创 2018-07-06 09:41:22 · 1135 阅读 · 0 评论 -
剑指offer第二版面试题41:数据流中的中位数(java)
题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。分析思路: 用两个堆保存数据,保证两个堆的数据保持平衡(元素个数相差不超过1)大顶堆存放的数据要比小顶堆的数据小当两个堆中元素为偶数个,将新加入元素加入到大顶堆,如果要加入的数据,比小顶堆的最小...原创 2018-07-05 09:48:05 · 1519 阅读 · 3 评论 -
剑指offer第二版面试题40:最小的k个数(java)
题目描述: 输入n个整数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。这道题最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。这种思路的时间复杂度是O(nlogn),面试官会提示我们还有更快的算法。分析1:O(n)的算法,只有当我们可以修改输入的数组时可用 我们可以基于Partition函数...原创 2018-07-05 09:12:18 · 996 阅读 · 0 评论 -
剑指offer第二版面试题39:数组中出现次数超过一半的数字(java)
题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例子说明:如输入一个长度为9的数组{ 1, 2, 3, 2, 2, 2, 5, 4, 2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 。分析1:基于Partition 函数的O(n)算法 数组中有一个数字出现的次数超过了数组长度的一半。如果把这个数组排序,那么排序之后位于数组中间的数字一定就是...原创 2018-07-03 10:07:04 · 1879 阅读 · 1 评论 -
剑指offer第二版面试题38:字符串的排列(java)
题目描述: 输入一个字符串,打印出该字符串中字符的所有排列。 例如输入字符串abc,则打印由字符a,b,c所能排列出来的所有字符串:abc,abc,bac,bca,cab,cba分析: 我们求整个字符串的排列,可以看成两步:首先求出所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。第二步固定第一个字符,求后面所有字符的排列。这个时候我们仍把后面的所有字符分成两部分:后面...原创 2018-07-03 08:42:38 · 969 阅读 · 0 评论 -
剑指offer第二版面试题37:序列化二叉树(java)
题目描述: 请实现两个函数,分别用来序列化和反序列化二叉树。分析: 如图: 题目实际上就是用序列来表示一棵二叉树,然后还可以根据这个序列重建二叉树。对于上图中的树,以前序遍历为例,先访问到1,然后2,然后4,4的左右子结点都为空,可以用一个特殊字符$替代,所以上图中的二叉树前序遍历表示就是“1,2,4,$,$,$,3,5,$,$,6,$,$”。 重建的时候,访问的第一个结点...原创 2018-06-04 12:02:57 · 1514 阅读 · 4 评论 -
剑指offer第二版面试题36:二叉搜索树与双向链表(java)
题目描述: 输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整树中结点指针的指向。比如如下图中的二叉搜索树,则输出转换之后的排序双向链表为: 分析:在二叉树中,每个结点都有两个指向子节点的指针。在双向链表中,每个结点也有两个指针,他们分别指向前一个结点和后一个结点。由于这两种结点的结构相似,同时二叉搜索树也是一种排序的数据结构,因此在理论上有...原创 2018-06-04 09:33:32 · 1683 阅读 · 2 评论 -
剑指offer第二版面试题35:复杂链表的复制(java)
题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)分析: 思路1: 先复制原始链表的结点 在元素链表的头结点开始找每个结点的random。每次都要从头开始找,然后连接起来,所以时间复杂度是o(n*n) 思路2:...原创 2018-05-25 18:50:05 · 623 阅读 · 0 评论 -
剑指offer第二版面试题34:二叉树中和为某一值的路径(java)
题目描述: 输入一颗二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。路径定义为从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。分析: 对于树的遍历一般就是深度遍历和广度遍历下四种中的一种,从根节点往下找到叶节点形成一条路径,若是和为给定的值这个路径便是需要找的路径,从根节点到叶节点边访问边相加判断可以采用先序遍历。 (1)若根节点的值大于给定的值或者根节点为空,...原创 2018-05-25 14:57:23 · 924 阅读 · 0 评论 -
剑指offer第二版面试题33:二叉搜索树的后序遍历序列(java)
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是返回true,否则返回false。假设输入的数组的任意两个数字互不相同。分析: 已知条件:后序序列最后一个值为root;二叉搜索树左子树值都比root小,右子树值都比root大。 1、确定root; 2、遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树; 3...原创 2018-05-25 14:23:53 · 511 阅读 · 0 评论 -
剑指offer第二版面试题32:从上到下打印二叉树(java)
题目一描述: 从上往下打印二叉树的每个节点,同一层的节点按照从左到右的顺序打印。例如输入下图的二叉树,则一次打印出8,6,10,5,7,9,11。 分析: 这道题实质上考察的就是树的遍历算法,只是这种遍历不是我们熟悉的前序、中序或者后序遍历。由于我们不太熟悉这种按层遍历的方法,可能一下也想不清楚遍历的过程。 因为按层打印的顺序决定应该先打印的根节点,所以我们从树的根节点开始分析。为了接...原创 2018-05-25 11:52:20 · 3262 阅读 · 0 评论 -
剑指offer第二版面试题31:栈的压入、弹出序列(java)
题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压栈序列,序列,4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。分析: 解决这个问题很直观的想法就是建立一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的...原创 2018-05-07 22:45:56 · 465 阅读 · 0 评论 -
剑指offer第二版面试题30:包含min函数的栈(java)
题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1).分析: 看到这个问题,我们的第一反应可能是每次压入一个新元素进栈时,将栈里的所有元素排序,让最小的元素位于栈顶,这样就能在O(1)时间得到最小元素了。但这种思路不能保证最后压入的元素能够最先出栈,因此这个数据结构已经不是栈了。 我们接着想到在...原创 2018-05-07 22:21:32 · 429 阅读 · 1 评论 -
剑指offer第二版面试题29:顺时针打印矩阵(java)
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵: 1, 2, 3, 4 5, 6, 7, 8 9, 10,11,12 13,14,15,16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.分析: 当遇到一个复杂的问题的时候,我们可以用图形来帮助我们来思考。由于是...原创 2018-05-05 17:07:56 · 3505 阅读 · 0 评论 -
剑指offer第二版面试题28:对称的二叉树(java)
题目描述: 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树和它的镜像是一样的,那么它是对称的。分析: 对于一棵二叉树,从根结点开始遍历, 如果左右子结点有一个为NULL,那么肯定不是对称二叉树; 如果左右子结点均不为空,但不相等,那么肯定不是对称二叉树; 如果左右子结点均不为空且相等,那么 遍历左子树,遍历顺序为:当前结点,左子树,右子树; 遍历右子树,遍历...原创 2018-05-05 12:25:12 · 881 阅读 · 0 评论 -
剑指offer第二版面试题27:二叉树的镜像(java)
题目描述: 请完成一个函数,输入一个二叉树,该函数输出它的镜像 二叉树节点定义:// 二叉树节点定义class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; ...原创 2018-05-05 11:09:15 · 449 阅读 · 0 评论 -
剑指offer第二版面试题26:树的子结构(java)
题目描述: 输入两棵二叉树A和B,判断B是不是A的子结构。 例如: 图中所示的两棵二叉树,由于A中有一部分子树的结构和B 是一样的,因此B是A的子结构。 分析: 要查找树A中是否存在和树B结构一样的子树,思路:第一步:先在树A中查找与根结点的值一样的结点,这实际就是树的先序遍历,当树A和树B为空时,定义相应的输出。如果树A某一结点的值和树B头结点的值相同,则调用doesTree1Ha...原创 2018-05-02 17:19:20 · 455 阅读 · 0 评论 -
剑指offer第二版面试题25:合并两个排序的链表(java)
题目描述: 输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入图中的链表1和链表2,则合并之后的升序链表3所示。 分析: 这是一个经常被各公司采用的面试题。在面试过程中,我们发现应聘者最容易犯两个错误:一是在写代码之前没有对合并的过程想清楚,最终合并出来的链表要么中间断开要么并没有递增排序;二是代码的鲁棒性方面存在问题,程序一旦有特殊的输入(如空链表)...原创 2018-05-02 16:49:46 · 602 阅读 · 0 评论 -
剑指offer第二版面试题24:反转链表(java)
题目描述: 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表的头结点。链表结点如下:public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}分析: 要想反转链表,对于结点i,我们要把它的...原创 2018-05-02 16:12:05 · 598 阅读 · 0 评论 -
剑指offer第二版面试题23:链表中环的入口节点(java)
题目描述: 如果一个链表中包含环,如何找出环的入口节点?分析: 可以用两个指针来解决这个问题。先定义两个指针P1和P2指向链表的头结点。如果链表中环有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。 剩下的问题就是如何得到环中结点的数目。我们可以使用一快一慢的两个指针...原创 2018-05-02 15:31:56 · 684 阅读 · 0 评论 -
剑指offer第二版面试题22:链表中倒数第k个节点(java)
题目描述: 输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1,2,3,4,5,6。这个链表的倒数第3个结点是值为4的结点。分析: 为了得到第K个结点,很自然的想法是先走到链表的尾端,再从尾端回溯K步。可是我们从链表结点的定义可以看出本题中的链表是单向链表,单向链表的结点只...原创 2018-05-02 14:54:18 · 688 阅读 · 0 评论 -
剑指offer第二版面试题21:调整数组顺序使奇数位于偶数前面(java)
题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。基本实现 如果不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有的数字往前面挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于没碰到一个偶数就需要移动O(n)个数字,因此总的时间复...原创 2018-05-02 12:07:47 · 744 阅读 · 0 评论 -
剑指offer第二版面试题20:表示数值的字符串(java)
题目描述: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示数值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。分析: 1、在数值之前可能有一个表示正负的’-‘或者’+’。接下来是若干个0到9的数位表示数值的整数部分(在某些小数里可能没有数值的...原创 2018-05-02 11:44:59 · 844 阅读 · 2 评论 -
剑指offer第二版面试题19:正则表达式匹配(java)
题目描述: 请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配分析: 这道题的核心其实在于分析’‘,对于’.’来说,它和任意字符都匹配,可把其当做普通...原创 2018-05-02 11:02:46 · 533 阅读 · 2 评论 -
剑指offer第二版面试题18:删除链表中的节点(java)
题目一描述: 给定单链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。分析: 在单链表中删除一个节点,最常规的方法无疑是从链表的头结点开始,顺序遍历查找要删除的节点,并在链表中删除该节点。 比如图a所表示的链表中,我们要删除节点i,可以从链表的头节点a开始顺序遍历,发现节点h的m_PNext指向要删除的节点i,于是我们可疑把节点h的m_PNext指向i的下一个节点即为j。...原创 2018-05-02 10:22:09 · 745 阅读 · 0 评论 -
剑指offer第二版面试题17:打印1到最大的n位数(java)
题目描述: 输入数字n,按顺序打印出从1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的3位数即999跳进面试官的陷阱: 这个题目看起来很简单。我们看到这个问题后,最容易想到的办法是求出最大的n位数,然后用一个循环从1开始逐个打印。于是我们很容易写出下面的代码。public static void print1ToMaxOfNDigits(int n) { ...原创 2018-04-30 17:17:28 · 771 阅读 · 0 评论 -
剑指offer第二版面试题16:数值的整数次方(java)
题目描述: 实现函数double Power(double base,int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。自以为很简单的解法: 由于不需要考虑大数问题,这道题看起来很简单,可能不少应聘者在看到题目30秒后就能写出如下的代码:public static double power(double base, int exp...原创 2018-04-30 16:12:29 · 495 阅读 · 0 评论 -
剑指offer第二版面试题15:二进制中1的个数(java)
题目描述: 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2。可能引起死循环的解法: 这是一道很基本的考察二进制和位运算的面试题。题目不是很难,面试官提出问题之后,我们很快就可以形成一个基本的思路:先判断整数二进制表示中最右边一位是不是1。接着把输入的整数右移一位,此时原来处于(从右边数起)第二位被移到最后...原创 2018-04-30 12:02:22 · 539 阅读 · 0 评论 -
剑指offer第二版面试题14:剪绳子(java)
题目描述: 给定一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]* k[1] * … *k[m]可能的最大乘积是多少? 例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。分析: 1、求一个问题的最优解; 2、整体的问题的最优解是依赖各个子问题的...原创 2018-04-30 10:22:33 · 1197 阅读 · 0 评论 -
剑指offer第二版面试题13:机器人的运动范围(java)
题目描述: 地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左,向右,向上,向下移动一格,但不能进入行坐标和列坐标的位数之和大于k的格子。例如:当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18;但它不能进入方格(35,38),因为3 + 5+3+8 = 19.请问该机器人最多能到达多少个格子?分析: 和面试题13类似,这个方格也可...原创 2018-04-28 23:49:53 · 585 阅读 · 0 评论 -
剑指offer第二版面试题12:矩阵中的路径(java)
问题描述: 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串”bcced”的路径,但是矩阵中不包含”abcb”路径,因为字符串的第一个字符b...原创 2018-04-28 21:51:27 · 650 阅读 · 3 评论 -
剑指offer第二版面试题11:旋转数组的最小数字(java)
题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。解题思路: 1、暴力解法,从头到尾遍历一次,我们就能找出最小的元素,复杂度为O(n),但是没有利用输入的旋转数组的特性,肯定达不到面试官的要求。 2、二分查找,这里的数...原创 2018-04-28 21:02:08 · 594 阅读 · 0 评论 -
剑指offer第二版面试题10:斐波那契数列(java)
题目一:写一个函数,输入n,求斐波那契数列的第n项。斐波那契数列的定义如下:1、效率很低效的解法,挑剔的面试官不会喜欢很多C语言的教科书在讲述递归函数的时候,都会拿Fibonacci作为例子,因此很多的应聘者对这道题的递归解法都很熟悉。下面是实现代码我们教科书上反复用这个问题来讲解递归的函数,并不能说明递归的解法最适合这道题目。面试官会提示我们上述递归的解法有很严重的效率问题要求我...原创 2018-04-24 20:50:00 · 609 阅读 · 1 评论 -
剑指offer第二版面试题9:用两个栈实现队列(java)
题目描述: 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能。分析: 我们通过一个具体的例子来分析该队列插入和删除元素的过程。首先插入一个元素a,不妨先把它插入到stack1,此时stack1 中的元素有{a},stack2为空。再压入两个元素b和c,还是插入到stack1中,此时st...原创 2018-04-17 22:20:37 · 668 阅读 · 0 评论