
剑指offer
另一只羊
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
面试题29 :数组中出现次数超过一半的数字
题目数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。解题思路方法一:首先将数组进行排序(快速排序),如果存在一个数字出现的次数超过数组长度的一半,那么此时第n/2个数字即为所求数字。 时间复杂度是:O(nlogn)方法二:修改了输入的数组原创 2017-06-27 16:50:32 · 441 阅读 · 0 评论 -
面试题36:数组中的逆序对
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如在数组{7, 5, 6, 4 中, 一共存在5 个逆序对,分别是(7, 6)、(7,5),(7, 4)、(6, 4)和(5, 4)。解题思路第一种:直接求解 顺序扫描整个数组。每扫描到一个数字的时候,逐个比较该数字和它后面的数字的大小。如果后面的数字比它小,则这两个数原创 2017-07-13 11:52:10 · 414 阅读 · 0 评论 -
面试题35:第一个只出现一次的字符
题目:在字符串中找出第一个只出现一次的字符。解题思路第一种:直接求解: 从头开始扫描这个字符串中的每个字符。当访问到某字符时拿这个字符和后面的每个字符相比较,如果在后面没有发现重复的字符,则该字符就是只出现一次的字符。如果字符串有n个字符,每个字符可能与后面的O(n)个字符相比较,因此这种思路的时间复杂度是O(n^2)。第二种:记录法 由于题目与字符出现的次数相关, 我们是不是可以统计每个字符在原创 2017-07-13 11:35:45 · 259 阅读 · 0 评论 -
面试题4:替换空格
题目:请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。public class Solution { public String replaceSpace(StringBuffer str) { if (str != null) { String原创 2017-06-02 23:54:00 · 221 阅读 · 0 评论 -
面试题3:数组:二维数组中的查找
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。原创 2017-06-02 23:10:32 · 254 阅读 · 0 评论 -
面试题18:树的子结构
题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)解题思路:二叉树—>递归操作代码实现:/**public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) {原创 2017-06-19 21:50:51 · 212 阅读 · 0 评论 -
面试题17:合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的代码实现:public class Test17 { public static class ListNode { int value; ListNode next; } /** * 输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排原创 2017-06-19 21:41:36 · 273 阅读 · 0 评论 -
面试题16 :反转链表
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。代码实现:尾插法/*public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}*/public class Solution { pub原创 2017-06-19 21:23:45 · 220 阅读 · 0 评论 -
面试题15 :链表中倒数第k个结点
题目:题目:输入一个链表,输出该链表中倒数第k 个结点.为了符合大多数人的习惯,本题从1 开始计数,即链表的尾结点是倒数第1 个结点.例如一个链表有6 个结点,从头结点开始它们的值依次是1 、2、3、4、5 、6。这个个链表的倒数第3 个结点是值为4 的结点.解题思路:为了实现只遍历链表一次就能找到倒数第k 个结点,我们可以定义两 个指针。第一个指针从链表的头指针开始遍历向前走k-1步,第二个指原创 2017-06-19 20:51:32 · 253 阅读 · 0 评论 -
面试题37:两个链表的第一个公共结点
题目:输入两个链表,找出它们的第一个公共结点。解题思路第一种:直接法 在第一个链表上顺序遍历每个结点,每遍历到一个结点的时候,在第二个链表上顺序遍历每个结点。如果在第二个链表上有一个结点和第一个链表上的结点一样,说明两个链表在这个结点上重合,于是就找到了它们的公共结点。如果第一个链表的长度为m,第二个链表的长度为n,显然该方法的时间复杂度是O(mn) 。第二种:使用栈 所以两个有公共结点而部分重原创 2017-07-13 11:56:26 · 372 阅读 · 0 评论 -
面试题19 :二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。解题思路:看图思考,发现规律。 通过后序遍历。代码实现:/**public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.va原创 2017-06-26 15:23:34 · 249 阅读 · 0 评论 -
面试题20:顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次扫印出每一个数字解题思路:可以发现,其实就是四种操作(右、下、左、上),循环执行。 记录每个元素的被访问状态,并且要注意边界条件的判断。代码实现:import java.util.ArrayList;public class Solution { public ArrayList<Integer> printMatrix(int [][]原创 2017-06-26 15:52:42 · 239 阅读 · 0 评论 -
面试题34:丑数
题目:把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。例如6、8 都是丑数,但14 不是,它包含因子7。习惯上我们把1 当做第一个丑数。解题思路第一种:逐个判断每个数字是不是丑数的解法,直观但不够高效。/** * 判断一个数是否只有2,3,5因子(丑数)原创 2017-07-07 17:48:37 · 642 阅读 · 0 评论 -
面试题28:字符串的排列
题目描述:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。解题思路:把一个字符串看成由两部分组成:第一部分为它的第一个字符,第二部分是后面的所有字符。在图4.14 中,我们用两种不同的背景颜色区分字符串的两部分。我们求整个字符串的排列,可以看成两步:首先求所有可能出现在第一个原创 2017-06-16 15:00:08 · 278 阅读 · 0 评论 -
面试题33:把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3, 32, 321},则扫描输出这3 个数字能排成的最小数字321323。解题思路:第一种:直观解法先求出这个数组中所有数字的全排列,然后把每个排列拼起来,最后求出拼起来的数字的最大值。第二种:排序解法找到一个排序规则,数组根据这个规则排序之后能排成一个最小的数字。要确定排序规则,就要比原创 2017-07-07 15:55:51 · 376 阅读 · 0 评论 -
面试题30:最小的k个数
题目输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。解题思路方法一:改变数组import java.util.Random;import java.util.ArrayList;public class Solution { public ArrayList<Integer> GetLeastNumbers_Solut原创 2017-06-27 20:54:14 · 452 阅读 · 0 评论 -
面试题38:数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{ 1, 2, 3, 3, 3, 3, 4, 5}和数字3 ,由于3 在这个数组中出现了4 次,因此输出4 。解题思路顺序查找,统计二分查找的递归形式,找出所有的target二分查找: 分别找到第一个target和最后一个target解法3就是利用改进的二分算法: 如何用二分查找算法在数组中找到第一个k,二分查找算法总是先拿数原创 2017-07-14 22:55:01 · 423 阅读 · 0 评论 -
面试题23:二叉树:从上往下打印二叉树
题目描述从上往下打印出二叉树的每个节点,同层节点从左至右打印。思路: 这道题实质是考查树的遍历算法。从上到下打印二叉树的规律:每一次打印一个结点的时候,如果该结点有子结点, 则把该结点的子结点放到一个队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复前面的打印操作,直至队列中所有的结点都被打印出来为止。 广度优先遍历。import java.util.ArrayList;impor原创 2017-06-08 15:10:33 · 225 阅读 · 0 评论 -
面试题22:栈:栈的压入和弹出序列
题目描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)思路: 解决这个问题很直观的想法就是建立一个辅助栈(一个数组),把输入的第一个序列中的数字原创 2017-06-08 14:30:31 · 318 阅读 · 0 评论 -
面试题21:栈:包含min函数的栈
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。方法一:只有一个栈空间,节省空间,但是min方法的时间复杂度是O(n)import java.util.Stack;public class Solution { private Stack<Integer> stack = new Stack<>(); public void push(int node原创 2017-06-07 17:01:59 · 290 阅读 · 0 评论 -
面试题14 :调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位予数组的后半部分。解题思路:这个题目要求把奇数放在数组的前半部分, 偶数放在数组的后半部分,因此所有的奇数应该位于偶数的前面。也就是说我们在扫描这个数组的时候, 如果发现有偶数出现在奇数的前面,我们可以交换它们的顺序,交换之后就符合要求了。因此我们可以维护两个指针,第一个指针初始化时指向数组的第一原创 2017-06-19 20:29:32 · 241 阅读 · 0 评论 -
面试题13:在O(1)时间删除链表结点
解题思路:一般情况下,删除链表中的某一结点D,需要从头开始遍历链表得到结点D的前驱结点,再进行删除操作,而此时的时间复杂度就是O(n)。 题目要求在O(1)时间内删除结点,就不可能对链表进行遍历操作;而遍历操作的目的是得到前驱结点,那么我们是不是可以通过直接得到的后继结点来达到删除的目的!代码实现:注意边界值!!!package jianzhi;public class Test13 {原创 2017-06-19 20:05:01 · 299 阅读 · 0 评论 -
链表:链表中环的入口结点
题目描述一个链表中包含环,请找出该链表的环的入口结点。方法一:思路:借助Collection容器来存储链表元素。/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}*/import java.util.H原创 2017-06-07 05:36:51 · 506 阅读 · 1 评论 -
字符串:表示数值的字符串
题目描述请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。方法一:public class Solution { public boolean isNumeric(char[] str) {原创 2017-06-07 01:07:53 · 378 阅读 · 0 评论 -
字符串:字符流中第一个不重复的字符
题目描述请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。 输出描述:如果当前字符流没有存在出现一次的字符,返回#字符。方法一:思路:用一个map来映射插入的字符和其个数;因为题目说要找出第一个不重复的字符,所以用一个list来存储原创 2017-06-06 23:17:27 · 323 阅读 · 0 评论 -
数组:数组中重复的数字
数组中重复的数字题目描述在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。方法一:审题:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 所以可以用一个标记数组flag[n],它的下标就代原创 2017-06-06 01:05:12 · 206 阅读 · 0 评论 -
数组:构建乘积数组
题目描述给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。方法一:暴力解决有很多重复的运算过程 时间复杂度:O(n^2)方法二:思考: (1)B[i]、B[i+1] 、B[i+2]之间有没有关联? (2)既然B[i]、B[i+原创 2017-06-05 20:20:40 · 329 阅读 · 0 评论 -
面试题26:复杂链表的复制
题目:请实现函数ComplexListNode clone(ComplexListNode head),复制一个复杂链表。在复杂链表中,每个结点除了有一个next 域指向下一个结点外,还有一个sibling 指向链表中的任意结点或者null。解题思路:图4.8 是一个含有5 个结点的复杂链表。图中实线箭头表示next 指针,虚线箭头表示sibling 指针。为简单起见,指向null 的指针没有画出。原创 2017-06-15 22:25:24 · 201 阅读 · 0 评论 -
面试题25:二叉树中和为某一值的路径
二叉树前序遍历!import java.util.ArrayList;class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } }/** * 题目:输入一棵二叉树和一个整数, 打印出二叉树中结点值的和为输入整数原创 2017-06-15 22:13:25 · 219 阅读 · 0 评论 -
面试题24:二叉搜索树的后序遍历序列
二叉搜索树后序遍历序列的特点!/** * 二叉搜索树(BST),即二叉排序树 * 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true。否则返回false。假设输入的数组的任意两个数字都互不相同。 * * 解题思路:后序遍历的特点 * 在后序遍历得到的序列中, 最后一个数字是树的根结点的值。 * 数组中前面的数字可以分为两部分: 第一部分是左子树结点原创 2017-06-15 22:02:16 · 214 阅读 · 0 评论 -
面试题2:实现Singleton模式
见博文:单例模式原创 2017-06-18 23:38:26 · 235 阅读 · 0 评论 -
面试题5:从尾到头打印链表
题目:输入一个链表,从尾到头打印链表每个节点的值。方法一:/*** public class ListNode {* int val;* ListNode next = null;** ListNode(int val) {* this.val = val;* }* }**/import原创 2017-06-03 00:36:21 · 379 阅读 · 0 评论 -
树:二叉树的下一个结点
题目描述给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。思路: 如果一个结点有右子树,那么它的下一个结点就是它的右子树中的左子结点。也就是说右子结点出发一直沿着指向左子结点的指针,我们就能找到它的下一个结点。 接着我们分析一个结点没有右子树的情形。 如果结点是它父节点的左子结点,那么它的下一个结点就是它原创 2017-06-07 15:54:07 · 297 阅读 · 0 评论 -
面试题12:打印1到最大的N位数
解题思路:方法一:利用数组来存储每一位的数值(0~9)。 总共有N位,每一位的数值可能为0~9中的一个数,其实就是全排列问题,从而可以利用递归的方式求解。递归的结束条件就是已经设置了数字的最后一位的值。package jianzhi;public class Test12 { /** * 输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3 一直到最大的原创 2017-06-19 19:47:46 · 454 阅读 · 0 评论 -
面试题11:数值的整数次方
题目:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。代码实现:public class Solution { public double Power(double base, int exponent) { if (base == 0 && exponent == 0) { throw原创 2017-06-19 17:57:23 · 213 阅读 · 0 评论 -
面试题10:二进制中1的个数
题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。解题思路:逐位判断是否是1。public class Solution { //java中int负数的二进制就是用补码来表示的 public int NumberOf1(int n) { if (n == 0) { return 0; } in原创 2017-06-19 16:54:05 · 329 阅读 · 0 评论 -
面试题9:斐波拉契数列及其变种
题目一:现在要求输入一个整数n,请你输出斐波那契数列的第n项。解题思路:由公式得到递归,效率太低!保存中间值,由下往上计算!时间复杂度是O(n)。代码实现:public class Test09 { /** * 写一个函数,输入n,求斐波那契(Fibonacci) 数列的第n项 * @param n Fibonacci数的项数 * @return 第n项的原创 2017-06-19 16:37:33 · 485 阅读 · 0 评论 -
面试题8:旋转数组中的最小值
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。解题思路:直接遍历一遍数组,找出最小值,时间复杂度为O(n),但是这不是面试官想要的答案;看到排序好的数组,可以想原创 2017-06-19 16:13:33 · 396 阅读 · 0 评论 -
面试题7:用两个栈实现队列
题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。代码实现:import java.util.Stack;public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); p原创 2017-06-19 15:37:25 · 259 阅读 · 0 评论 -
面试题6:重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如:前序遍历序列{ 1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8,6},重建出下图所示的二叉树并输出它的头结点。代码实现:public class Test06 { /** * 二叉树节点类 */原创 2017-06-19 15:28:22 · 285 阅读 · 1 评论