算法-剑指Offer-java
ouyangyanlan
这个作者很懒,什么都没留下…
展开
-
序列化和反序列化二叉树(java版)
【题目描述】请实现两个函数,分别用来序列化和反序列化二叉树【解题思路1】 //1. 利用前序遍历序列化二叉树,然后从记录的字符串中反序列化二叉树。 //2. 遇到空节点需要用特殊字符加以标记。如“#” //3. 单纯用前序遍历无法唯一确定一颗二叉树。所以该方法严格来讲,是错误的。但通过了牛客的测试。给个思路参考。public class Solution { public int in原创 2017-06-06 11:15:04 · 6343 阅读 · 2 评论 -
树的子结构(java版)
【题目描述】输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)【解题思路】 //1. 从根节点开始判断,判断树root2是不是root1的子树。 //2. 如果不是,再递归判断root2是不是root1.left的子树。 //3. 如果第二步没成立,则再判断root2是不是root1.right的子树。 //4. 直到返回true,或者递归结束。pu原创 2017-06-11 16:45:54 · 525 阅读 · 0 评论 -
二叉树的镜像(java版)
【题目描述】操作给定的二叉树,将其变换为源二叉树的镜像。【输入描述】【解题思路】 //1. 交换左子树和右子树//递归public class Solution { public void Mirror(TreeNode root) { if(root == null){ return; } if(root != n原创 2017-06-10 16:26:33 · 687 阅读 · 0 评论 -
栈的压入、弹出序列(java版)
【题目描述】输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)【解题思路】 链接:https://www.nowcoder.com/questionTe原创 2017-06-09 11:26:47 · 937 阅读 · 0 评论 -
从上往下打印二叉树(java版)
【题目描述】从上往下打印出二叉树的每个节点,同层节点从左至右打印。【解题思路】 //1. 层序遍历二叉树。 //2. 使用一个ArrayList记录下依次访问到的节点。import java.util.ArrayList;import java.util.LinkedList;import java.util.Queue;public class Solution { public原创 2017-06-09 10:40:49 · 847 阅读 · 0 评论 -
二叉搜索树的后序遍历序列(java版)
【题目描述】输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。【解题思路】BST的后序序列的合法序列是,对于一个序列S,最后一个元素是x (也就是根),如果去掉最后一个元素的序列为T,那么T满足:T可以分成两段,前一段(左子树)小于x,后一段(右子树)大于x,且这两段(子树)都是合法的后序序列。完美的递归定义 。原创 2017-06-09 10:35:56 · 1195 阅读 · 0 评论 -
二叉搜素树与双向链表(java版)
【题目描述】输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。注:不能创建新的结点,理解为不能显式的new一个出来。【解题思路1】 //1. 利用中序遍历的思想来完成。 //2. 给定一个指针用来存储中序遍历的第一个节点,作为双向链表的头指针。 //3. 对于遍历到的当前节点,若是第一个节点,则存储起来。否则,将上一个节点的右指针原创 2017-06-09 10:10:46 · 892 阅读 · 0 评论 -
连续子数组的最大和(java版)
【题目描述】HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度原创 2017-06-09 09:19:27 · 846 阅读 · 0 评论 -
整数中1出现的次数(从1到n整数中1出现的次数)(java版)
【题目描述】求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。【解题思路1】 //1. 直接遍历给定区间。 //2. 对遍历的每个数,判断其包含的1的个数。结果累加。原创 2017-06-08 11:47:34 · 1379 阅读 · 0 评论 -
把数组排成最小的树(java版)
【题目描述】输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。【解题思路】 //1. 利用一个List存储所有的整数。 //2. 对List的元素排序。比较器是自定义的。使用了java自带的compareTo()函数。 排序规则如下: * 若ab > ba原创 2017-06-08 11:17:05 · 1072 阅读 · 0 评论 -
丑数(java版)
【题目描述】把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。【题目解释】原题中的描述并不确切,这里做一下详细些的解释。原题的本意是,丑数是可以通过不断的除2、3、5,最后等于1的数字。其中2、3、5可以重复出现。即丑数可以通过2、3、5的乘积来表示。所以,虽然8包含因子4原创 2017-06-08 10:55:44 · 1533 阅读 · 0 评论 -
数组中的逆序对(java版)
【解题思路】在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 【输入描述】题目保证输入的数组中没有的相同的数字 数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100原创 2017-06-08 10:33:10 · 1690 阅读 · 0 评论 -
两个链表的第一个公共结点(java版)
【题目描述】输入两个链表,找出它们的第一个公共结点。注:默认为单链表,且无环【解题思路】 //1.两个单链表若存在公共结点,则从第一个公共结点开始,后面的结点都是公共的。 //2.比较两个链表的长度。设置两个指针,分别指向两个链表的头结点。较长的链表的指针先走|len1-len2|步。然后两个指针同时向后移动,两个指针相遇时,即为两个链表的第一个公共结点。public class Solutio原创 2017-06-08 10:03:27 · 1208 阅读 · 0 评论 -
二叉树的深度(java版)
【题目描述】输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。【解题思路1】 //1. 采用递归实现。当前节点的深度,等于左子树深度和右子树深度的最大值+1。public class Solution { public int TreeDepth(TreeNode root) { if(root == n原创 2017-06-08 09:22:06 · 1301 阅读 · 0 评论 -
反转链表(java版)
【题目描述】输入一个链表,反转链表后,输出链表的所有元素。【解题思路1】 //1. 只反转链表的值,并不是真正的把结点交换。 //2. 从第一个结点开始,找关于中间轴对称的结点,然后交换它们的值。public class Solution { public ListNode ReverseList(ListNode head) { if(head == null || h原创 2017-06-12 09:10:27 · 404 阅读 · 0 评论 -
链表中倒数第k个结点(java版)
【题目描述】输入一个链表,输出该链表中倒数第k个结点。【解题思路1】 //1.设置两个指针,inx1先向后移动k-1步,inx2不动。 //2.然后同时向后移动,inx1到达结尾的时候,inx2刚好为倒数第k个结点。 //3.注意临界情况。如输入链表为空,k<=0,或者链表长度小于k等public class Solution { public ListNode FindKthToTa原创 2017-06-12 09:26:08 · 497 阅读 · 0 评论 -
变态跳台阶(java版)
【题目描述】一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。【解题思路1】 //1.用Fib(n)表示跳上n阶台阶的跳法数。如果按照定义,Fib(0)肯定需要为0,否则没有意义。但是我们设定Fib(0) = 1;n = 0是特殊情况,通过下面的分析就会知道,强制令Fib(0) = 1很有好处。ps. Fib(0)等于几都不影响我们解题,原创 2017-06-13 15:26:50 · 899 阅读 · 1 评论 -
跳台阶(java版)
【题目描述】一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。【解题思路】 //1.对于第n个台阶来说,只能从n-1或者n-2的台阶跳上来,所以F(n) = F(n-1) + F(n-2) //2.斐波拉契数序列,初始条件 n=1:只能一种方法 n=2:两种 递归一下就好了 //3. 当测试用例比较大时,递归可能会产生超时。public class原创 2017-06-13 15:09:11 · 622 阅读 · 0 评论 -
斐波那契序列(java版)
【题目描述】大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39【分析】 1. 斐波那契序列满足: F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 2. 如:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …【解题思路1】 //1. 利用通项公式来解答 public clas原创 2017-06-13 14:13:27 · 962 阅读 · 0 评论 -
旋转数组中的最小数字(java版)
【题目描述】把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。【解题思路1】 //1. 遍历数组,逐个比较,找到最小值。import java.util.ArrayList原创 2017-06-13 11:46:02 · 696 阅读 · 0 评论 -
用两个栈实现队列(java版)
【题目描述】用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。【解题思路1】 //1. 声明两个栈s1和s2。s1作为主栈,s2作为辅助栈。 //2. 为了达到队列先进先出的功能, 每次执行push操作时,先把s1的元素都压栈到s2中,然后将当前元素入栈s1。 //3. 再将s2的元素依次弹出,压入栈s1中,即实现了先入的元素更接近栈顶。 //4. 每次执行原创 2017-06-13 11:22:10 · 2584 阅读 · 1 评论 -
重建二叉树(java版)
【题目描述】输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。【解题思路1】 //1. 先序遍历中,第一个结点即根节点。根据根节点,可以将中序遍历序列分为两部分,左边的即左子树,右边的即右子树。 //2. 根据其原创 2017-06-13 11:04:16 · 1480 阅读 · 0 评论 -
从尾到头打印链表(java版)
【题目描述】输入一个链表,从尾到头打印链表每个节点的值。【解题思路1】 //1. 遍历链表,使用一个ArrayList存储各个链表结点。 //2. 将ArrayList关于对称中心,进行翻转。得到的ArrayList即为从尾到头打印的顺序。//实现一import java.util.ArrayList;public class Solution { public ArrayList<I原创 2017-06-13 10:51:14 · 1106 阅读 · 0 评论 -
替换空格(java版)
【题目描述】请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。【解题思路1】 //1.利用已有的库函数public class Solution { public String replaceSpace(StringBuffer str) { String strs =原创 2017-06-13 10:21:47 · 580 阅读 · 0 评论 -
二维数组中的查找(java版)
【题目描述】在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。【解题思路1】 //1. 按行遍历二维数组,当前行遍历中,遇到比目标大的数字,则停止遍历。进入下一行的遍历。直到找到该数字,或遍历结束。public class Solution { public boolean原创 2017-06-13 10:00:34 · 1503 阅读 · 0 评论 -
矩形覆盖(java版本)
【题目描述】我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?【解题思路】 //1. 当target为0时,返回0。 //2. 当target为1时,返回1。 //3. 当target为2时,有两种排法,或者竖排,或者横排。返回2. //4. 当target大于2时,从大矩形的最左侧开始排。记排法为f(n)。此时第原创 2017-06-12 10:53:26 · 558 阅读 · 0 评论 -
二进制中1的个数(java版)
【题目描述】输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。【解题思路1】 //1.利用库函数转化为二进制数,然后将二进制数转为字符数组。 //2.遍历数组,计数1的个数。public class Solution { public int NumberOf1(int n) { int count = 0; String str = Int原创 2017-06-12 10:39:24 · 691 阅读 · 0 评论 -
数值的整数次方(java版)
【题目描述】给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。【解题思路1】 //1.使用库函数public class Solution { public double Power(double base, int exponent) { return Math.pow(base, exponent); }原创 2017-06-12 10:04:43 · 2911 阅读 · 1 评论 -
调整数组顺序使奇数位于偶数前面(java版)
【题目描述】输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。【解题思路1】 //1. 声明一个和原数组等长的数组。 //2. 计算出奇数的个数。遍历原数组,如果是奇数,则放到数组的前半部分。如果是偶数,则放到后半部分。public class Solution {原创 2017-06-12 09:53:30 · 634 阅读 · 0 评论 -
表示数值的字符串(java版)
【题目描述】请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示数值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。【解题思路】 //1. 合法的数值可以表示为public class Solution { private int i原创 2017-06-07 20:52:17 · 3331 阅读 · 1 评论 -
平衡二叉树(java版)
【题目描述】输入一棵二叉树,判断该二叉树是否是平衡二叉树。注:注意平衡二叉树和平衡二叉搜索树的区分。有的书中混淆了两个概念。这里的平衡二叉树只关注是否平衡。【解题思路】 //1. 平衡二叉树的定义是,满足任何一个节点的左右子树高度差都不大于1 //2. 递归处理。先判断根节点是否满足左右子树高度差的关系。然后判断左子树是否满足平衡二叉树的定义,然后是判断右子树。只有所有的节点都满足平衡二叉树的定原创 2017-06-07 16:05:53 · 992 阅读 · 0 评论 -
数据流中的中位数(java版)
【题目描述】如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。【解题思路】 //1. 声明一个List,存储每次读入的字符 //2. 求当前list中的中位数import java.util.ArrayList;import java.util.Arrays;原创 2017-06-06 10:53:50 · 4983 阅读 · 1 评论 -
滑动窗口的最大值(java版)
【题目描述】给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5原创 2017-06-06 10:16:28 · 4285 阅读 · 0 评论 -
矩阵中的路径(java版)
【题目描述】请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串”bcced”的路径,但是矩阵中不包含”abcb”路径,因为字符串的第一个字符b占据原创 2017-06-06 09:38:36 · 4647 阅读 · 1 评论 -
二叉树中和为某一值的路径(java版)
【题目描述】输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。【解题思路】 根据路径的定义,选择树的先序遍历作为流程框架。动态保存根节点到当前节点的path。若当前节点为叶子节点,则判断路径和是否为给定的整数值。直到树的遍历结束。【源码1】链接:https://www.nowcoder.com/questio原创 2017-05-10 12:00:31 · 3371 阅读 · 0 评论 -
最小的k个数(java版)
【题目描述】输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。【解题思路1】 //1.对数组按照从小到大的顺序,进行全排序。 //2.取数组的前k个节点 //3.注意输入的k的边界情况【源码1】import java.util.ArrayList;import java.util.Arrays;public class原创 2017-05-15 15:22:00 · 1382 阅读 · 0 评论 -
数组中出现次数超过一半的数字(java版)
【题目描述】数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。【解题思路1】 先来看一种最简单的解法,算法复杂度为O(n*log(n)) //1.对数组进行排序,然后遍历 //2.遍历过程中,记录当前元素的出现次数,若超过数组长度的一半原创 2017-05-12 23:16:53 · 1815 阅读 · 0 评论 -
复杂链表的复制(java版)
【题目描述】输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)【节点定义】/*public class RandomListNode { int label; RandomListNode next = null;原创 2017-05-13 17:42:52 · 2206 阅读 · 0 评论 -
第一个只出现一次的字符(java版)
【题目描述】在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符,并返回它的位置。【注意】 1.题目中描述字符串长度>1, 但是在实际操作中发现,牛客输入的测试用例中出现了空字符串,即长度为0的情况,截止到发文为止,已提交纠错申请,请注意。 2. 测试用例中出现了小写字符串的测试用例。 3. 若输入空串,需要返回 -1。题目也未提及到。【解题思路1】暴原创 2017-05-23 22:53:45 · 2099 阅读 · 0 评论 -
数字在排序数组中出现的次数(java版)
【题目描述】统计一个数字在排序数组中出现的次数。【解题思路1】 //1. 直接解,遍历一次数组,累计出现次数。【源码1】public class Solution { public int GetNumberOfK(int [] array , int k) { int num = 0; for(int a: array){ if(a原创 2017-05-23 22:32:15 · 1391 阅读 · 0 评论