
剑指offer
CurryXu
这个作者很懒,什么都没留下…
展开
-
面试题(三)数组中的重复数字
题目:找出数组中重复的数字。在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,若输入长度为7的数组{2, 3, 1, 0, 2 , 5, 3},则输出2或者3。思路: 若原数组中无重复的元素,则对原数组排序后下标为i的数组元素为i。受此启发我们可以重排原数组:从头到尾扫描原创 2018-01-31 16:53:39 · 348 阅读 · 0 评论 -
面试题(十七)打印1到最大的n位数
题目:输入数字n,按顺序打印出从1到最大的n位十进制数。如输入3,则打印出1、2、3直到最大的3位数999。思路:一种思路是算出10的n次方,再以其为for循环上界输出1到最大的n位十进制数。但应注意若n很大,则整型变量或长整型变量无法存放10的n次方,所以这是个大数问题,应该用字符数组(或整型数组,但会浪费更多内存)来表示大数。可以发现所有的n位十进制数其实就是n个从0到9的全排列,可以用递归来表原创 2018-02-22 12:35:14 · 306 阅读 · 0 评论 -
面试题(二十一) 调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。思路:若没有“保证奇数之间、偶数之间的相对位置不变”这一要求,可以使用一前一后两个指针来将所有奇数移动到数组前半部分,所有偶数移动到数组后半部分。此时可以借鉴插入排序的思想,在遍历数组的过程中将奇数和偶数移动到满足要求的位置原创 2018-02-23 23:16:02 · 312 阅读 · 0 评论 -
面试题(二十三) 链表中倒数第k个节点
题目:输入一个链表,输出该链表中倒数第k个节点。链表的定义如下:public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }思路:首先要注意代码的鲁棒性:当输入链表节点的数量小于k时,应该返回null。定义两个指针,第一个指针先从头原创 2018-02-24 19:48:03 · 296 阅读 · 0 评论 -
面试题(二十二)(扩展)求链表的中间节点
题目:求链表的中间节点。若链表节点数为偶数,返回中间两个节点中的任意一个。思路:可以定义两个指针,同时从链表的头节点出发,一个指针一次走一步,一个指针一次走两步。当走得快的指针走到链表末尾时,走得慢的指针正好在链表的中间。代码(含测试代码):public class FindMidInList{ public static void main(String[] args) {原创 2018-02-24 20:34:26 · 238 阅读 · 0 评论 -
面试题(二十七) 二叉树的镜像
题目:操作给定的二叉树,将其变换为源二叉树的镜像。思路:画图分析可知,在遍历二叉树的过程中将节点的左右子树交换即可。代码(递归实现,已在牛客网AC):public void Mirror(TreeNode root) { if(root == null) return; if(root.left == null && root.right ==原创 2018-03-03 23:24:56 · 205 阅读 · 0 评论 -
面试题(二十八)对称的二叉树
题目:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。思路:针对二叉树的前序遍历定义一种对称的遍历算法:先遍历父节点,再遍历其右子节点,最后遍历左子节点。如果一个二叉树的前序遍历结果和对称遍历算法结果相同,那么这个二叉树便是对称的。代码(已在牛客网AC): boolean isSymmetrical(TreeNode pRoot)原创 2018-03-03 23:29:14 · 241 阅读 · 0 评论 -
面试题(二十九) 顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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-03-03 23:35:26 · 214 阅读 · 0 评论 -
面试题(三十四)二叉树中和为某一值的路径
题目:输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。思路:首先要注意:必须是从根节点到叶节点的路径才是有效的路径,若是根节点到内部节点的一条路径,则无效。 由于二叉树递归的结构特性,所以可以考虑用递归解题: 1)首先判断输入整数和当前节点的值是否相同,若相同且该节点为叶节点,则将当前路径放入符合题意的路径集合中,然原创 2018-03-11 20:57:44 · 270 阅读 · 0 评论 -
面试题(三十五)复杂链表的复制
题目: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)思路: 解法一:以空间换时间。整个过程分两步:首先遍历原链表,创建复制结点,并完成复制节点的val、next域的赋值,此过程中建立一个Map,存储原节点和其复制节点的映射关系。然原创 2018-03-11 21:21:38 · 200 阅读 · 0 评论 -
面试题(三十六)二叉搜索树与双向链表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路:二叉搜索树的题目可以想到由递归来解决。由于要转换成排序的双链表,因此需要使用二叉树的前序遍历。先转换左子树,然后将根节点与左子树转换成的链表连接起来,再连接上右子树的转换链表即可。代码实现:// 返回排序双链表的头节点 public TreeNode Convert(原创 2018-03-11 21:36:54 · 292 阅读 · 0 评论 -
面试题(二十三) 链表中环的入口节点
题目:一个链表中包含环,请找出该链表的环的入口结点。思路:关键是要想到:如果链表存在环,则设置一快一慢两个指针同时从链表头出发,那么快的指针必定会追上慢的指针,并且相遇的节点为环中的一个节点。然后再让指向相遇节点的指针绕着环一圈便可以计算出环的长度length。最后再让一个指针从链表头节点出发,另一个指针从链表的第length+1个节点出发,两个指针以相同速度往后移动,相遇的节点便为链表的环的入口节原创 2018-02-25 22:27:52 · 322 阅读 · 0 评论 -
面试题(十六)数值的整数次方
题目:实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。思路:主要是要注意0的0次方在数学上无意义,同时0的负数次方是非法的。要做好这些情况的处理。代码(已在牛客网AC):public class Solution { //设置全局变量以标识出无意义的情况 boolean原创 2018-02-21 22:39:38 · 255 阅读 · 0 评论 -
面试题(十五) 二进制中1的个数
题目:实现一个函数,输入一个整数,输出该数二进制表示中1的个数。思路1:Java支持对整型变量直接进行位运算。可将整数的二进制表示中的各位与1进行位与,从而计算该数二进制表示中1的个数。代码(已在牛客网AC):public int NumberOf1(int n) { int count = 0; int flag = 1; // flag和n都为原创 2018-02-21 21:06:47 · 337 阅读 · 0 评论 -
面试题(四)不修改数组找出重复的数字
题目: 不修改数组找出重复的数字。在一个长度为n+1的数组中的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。在不修改输入数组的情况下找出数组中任意一个重复数字。例如输入长度为8的数组{2, 3, 5, 4, 3, 2, 6, 7},则对应输出的是2或者3。思路:(类似于2分查找) 对于一个整数范围i1~i2,如果在这个范围内的整数的数量超过i2-i1+1,那么此范围内的整数中必然原创 2018-01-31 17:20:45 · 2300 阅读 · 3 评论 -
面试题(四)二维数组中的查找
题目: 在一个二维数组中,每一行都按照从左往右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组与一个整数,判断数组中是否含有该整数。思路: 从二维数组的右上角元素开始进行查找。如果这个元素大于待查找的整数,则从查找范围中去除该元素所在列;若此元素小于待查找整数,则从查找范围中去除该元素所在行。取二维数组剩余部分的右上角元素,再次进行同样的查找过程,直到找原创 2018-02-01 19:38:50 · 308 阅读 · 0 评论 -
面试题(五)替换空格
题目:实现一个函数,把字符串中的每个空格替换成“%20”。如输入“We are happy”,输出“We%20are%20happy”。思路: 1. 可以从前到后扫描字符串,每遇到空格便将其后的元素往后移动两位,然后写入“%20”。这样会有元素被移动多次。算法的时间复杂度为O(n^2)。 2. 先扫描字符串得到字符串中空格的数量,再从后往前扫描字符串:设置两个指针,一个指针newEnd指向替换原创 2018-02-01 20:00:28 · 289 阅读 · 0 评论 -
面试题(九)用两个栈实现队列
题目: 用两个栈实现一个队列,需要实现队列的在尾部插入节点和在头部删除节点的功能。队列的声明如下:public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); public void push(int nod原创 2018-02-09 23:05:29 · 356 阅读 · 1 评论 -
面试题(六)从尾到头打印链表
题目: 输入一个链表的头节点,从尾到头反过来打印每个节点的值。链表节点定义为:public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }思路一(破坏原链表型): 声明reverse结点引用变量指向逆序链表的头节点,first结点引用原创 2018-02-05 16:56:39 · 282 阅读 · 0 评论 -
面试题(七)重建二叉树
题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。树节点的定义如下:public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }思路: 前序遍历结果的第一个数字是二叉树原创 2018-02-05 21:34:06 · 223 阅读 · 0 评论 -
面试题(八)二叉树的下一个节点
题目: 给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左右子节点的指针,还有一个指向父节点的指针。树节点的定义: class TreeNode{ TreeNode left; TreeNode right; TreeNode parent; int val; }思路: 画原创 2018-02-05 22:59:49 · 312 阅读 · 0 评论 -
面试题(三十三)二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。思路:二叉搜索树的后序遍历结果的特点:序列的最后为根节点,序列的前半部分为根节点的左子树,所有元素小于根节点,后半部分为右子树,所有元素大于根节点。因此解题步骤如下: 1)确定根节点 2) 从左往右遍历序列,直到发现第一个大于根节点的元素x。此元素之前原创 2018-03-08 17:17:57 · 242 阅读 · 0 评论 -
面试题(二十四) 反转链表
题目:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。链表节点的定义如下:public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}思路:定义first指针指向原链表中待反转的节点,second指针指向原创 2018-02-28 23:52:16 · 260 阅读 · 0 评论 -
面试题(二十五) 合并两个排序的链表
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。思路:用递归实现该算法较为简便。、代码(已在牛客网 AC):public ListNode Merge(ListNode list1,ListNode list2) { if(list1 == null) return list2; if(l原创 2018-02-28 23:56:54 · 193 阅读 · 0 评论 -
面试题(二十六) 树的子结构
题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)思路:要查找树A中是否存在和树B结构一样的子树,可以分为两步:第一步是在树A中找到和树B的根节点的值一样的节点R;第二步是判断以R为根节点的子树是不是包含和树B一样的结构。第一步查找树A中是否存在和树B的根节点值一样的节点可以通过遍历树A实现;第二步判断R为根节点的子树是否包含和树B一样的结构也可以通过递原创 2018-03-01 00:07:16 · 195 阅读 · 0 评论 -
(面试题 45)把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。思路一:计算得到数组中所有数字的全排列,然后求全排列中最小的数。 计算数组中所有数字的全排列的方法采用回溯法,通过递归实现。该算法的时间复杂度为O(n!),因为会求数组中所有数字的全排列。代码实现:import java原创 2018-04-04 17:22:57 · 513 阅读 · 0 评论