剑指Offer
Fly_Fly_Zhang
初学java
展开
-
剑指Offer-二叉树的下一节点
题目: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 思路: 中序遍历为LVR。我们进行分析, 若当前节点有右子树,那么下一节点肯定在其右子树,对右子树一直进行向左遍历。 若当前节点为父节点的左子树,直接返回父节点,若不是,则一直向上遍历满足条件的父节点。 代码实现: /* public class Tree...原创 2019-07-13 17:27:35 · 150 阅读 · 0 评论 -
剑指Offer(35)-第一个只出现一次的字符
题目: 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)。 思路: 我们可以使用map来统计各字符出现的字数,然后再遍历字符串,就可以找到第一个只出现一次的字符。 代码实现: import java.util.HashMap; public class Solution { pu...原创 2019-06-18 09:33:29 · 118 阅读 · 0 评论 -
剑指Offer(34)-丑数
题目: 把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 方法一: 方法二: 根据丑数的定义,丑数是另一个丑数乘以2,3,5的结果(1除外)。因此,我们可以创建一个数组,里面的丑数都是排好序的。 我们假设当前数组中最大的丑数是M,那么我们如何得到下一大的丑数? 该丑...原创 2019-06-18 09:15:27 · 149 阅读 · 0 评论 -
剑指Offer(33)-把数组排成最小的数
题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。 思路: 这道题主要的难点在于对两个元素的比较,这里不可以使用简单的比较大小的方法。要比较两个元素m,n的大小,那么我们就需要比较nm和mn的大小。因此我们需要使用到比较器。能够装元素,又能够进行比较排序,我们想当然...原创 2019-06-17 21:00:18 · 212 阅读 · 0 评论 -
剑指Offer(32)-从1到n的整数中1的个数
题目: 求出1~ 13的整数中1出现的次数,并算出100~1300的整数中1出现的次数? 为此他特别数了一下1 ~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。 方法一: 遍历每一个数字,得到其1的个数;利用对整数的各位进行求余,判...原创 2019-06-17 20:26:36 · 277 阅读 · 0 评论 -
剑指Offer(31)-连续子数组的最大和
题目: 输入一个整型数组,数组里有正数也有负数。数组中一个或连续多个整数组成一个字数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。 方法一: 从头到尾累加,前一个累加值num>0则与当前值直接相加得到当前累加值,若前一个累加值num<0,则当前累加值为当前值。接着比较当前累加值与历史累加值大小。 public class Solution { public int F...原创 2019-06-17 18:06:23 · 127 阅读 · 0 评论 -
剑指Offer(51)-构建乘积数组
题目: 给定一个数组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]。不能使用除法。 思路: 分别从左右两边开始连乘,但是均不乘本位,那么左边的i-1就是i左边数的乘积,i+1就是i右边数的乘积,然后i-1 * i+1 。那么就会得到我们想要的结果。 代码实现: import java.util...原创 2019-06-21 15:46:35 · 179 阅读 · 0 评论 -
剑指Offer(50)-数组中重复的数字
题目: 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。 思路: 我们采用数组角标作为0-n-1的数字标识。 代码实现: public class Solution { //...原创 2019-06-21 15:26:36 · 160 阅读 · 0 评论 -
剑指Offer(49)-把字符转换成数字
题目: 一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。 输入描述: 输入一个字符串,包括数字字母符号,可以为空 输出描述: 如果是合法的数值表达则返回该数字,否则返回0 方法一: 采用从高位遍历的方法,每当遍历一次,就给整体*10,让出...原创 2019-06-21 14:38:40 · 391 阅读 · 0 评论 -
剑指Offer(28)-字符串的全排列
题目: 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。 方法一:递归算法: 我们将字符串看成两部分组成,第一部分为它的第一个字符,第二部分为后面所有的字符。首先求所有可能出现再第一个位置的...原创 2019-06-11 16:05:26 · 458 阅读 · 0 评论 -
剑指Offer(47)-不用加减乘除的加法
题目: 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。 思路: 两个数异或等于二进制加法的本位相加,与得到进位。 循环: public class Solution { public int Add(int num1,int num2) { while(num2!=0){ //注意,这里不能写大于>,因为有可能是两个负数相加。 ...原创 2019-06-20 21:19:52 · 146 阅读 · 0 评论 -
剑指Offer(36)-数组中的逆序对(O(nlogn))
题目: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 输入描述: 题目保证输入的数组中没有的相同的数字 数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<...原创 2019-06-18 12:08:10 · 402 阅读 · 0 评论 -
剑指Offer(37)-两条链表的第一个公共节点(O(n))
题目: 输入两个链表,找出它们的第一个公共结点。 思路: 本题我们只需要使用一个点,l1+l2=l2+l1; 如图,红色部分为两条链表的公共部分,我们采用cur1,cur2,分别遍历两条链的做法,再分别遍历第二条链时,如果存在公共链,那么亦步亦趋的比较就会得到第一个节点。如果没有公共链表,那么两条链也会同时结束。 代码实现: /* public class ListNode { int ...原创 2019-06-18 12:33:17 · 191 阅读 · 0 评论 -
剑指Offer(38)-数字在排序数组中出现的次数
题目: 统计一个数字在排序数组中出现的次数。 方法一:二分查找 因为数组是排序数组,因此我们使用二分查找找到k,然后左右遍历统计k的个数。 public class Solution { private int binary(int[] array,int l,int r,int k){ if(l>r){ return 0; }...原创 2019-06-18 15:44:30 · 124 阅读 · 0 评论 -
剑指Offer(39_2)-判断一颗二叉树是不是平衡二叉树
题目: 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 思路: 采用后续遍历,判断返回的左右子树的高度差是不是大于1。 代码实现: public class Solution { private int TreeDepth(TreeNode root) { if(root==null) return 0; int l=TreeDept...原创 2019-07-13 16:39:59 · 164 阅读 · 0 评论 -
剑指Offer(39)-二叉树的深度
题目: 输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 思路: 我们每次比较左右子树的深度,得到深度最大的,加一在返回上层递归调用。 代码实现: /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right ...原创 2019-07-13 16:23:37 · 134 阅读 · 0 评论 -
剑指Offer(27)-二义搜索树与双向链表
题目: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 思路: 对于二叉树,只要想到有序,那么我们直接想到中序遍历。 中序遍历为LVR。此题让我们返回有序链表的头结点。如果我们使用LVR,并且L返回的是头结点,那么再 代码实现: /** public class TreeNode { int val = 0; Tr...原创 2019-07-13 16:15:14 · 133 阅读 · 0 评论 -
剑指Offer(25)-二叉树中和为某一值的路径
题目: 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前) 思路: 我们采用递归的思路进行处理,每当深度递归时将当前节点值压入临时链表list中。若当前节点恰好为叶子节点并且target为0时,那么这就是我们找到的一条路径。我们将此条路径压入lis...原创 2019-07-13 15:05:43 · 246 阅读 · 0 评论 -
剑指Offer(24)-二叉搜索树的后续遍历序列
题目: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 思路: 后序遍历为LRV。因此数组最后一位为根节点。数组前半段为其左子树,后半段为其右子树,再每层递归时,我们找到左右子树的分割点,分别判断左右子树是否小于/大于根节点,然后在对左右子树进行递归。 代码实现: public class Solution...原创 2019-07-13 12:35:59 · 199 阅读 · 0 评论 -
剑指Offer(23)-从上往下打印二叉树
题目: 从上往下打印出二叉树的每个节点,同层节点从左至右打印。 思路: 使用一个队列,将左右孩子分别压入队列中,每次取出一个元素重复之。那么实际上就是按层进行存放的。 代码实现: import java.util.ArrayList; /** public class TreeNode { int val = 0; TreeNode left = null; TreeNod...原创 2019-07-13 12:11:06 · 147 阅读 · 0 评论 -
剑指Offer(19)-二叉树的镜像
题目: 题目描述: 操作给定的二叉树,将其变换为源二叉树的镜像。 输入描述: 二叉树的镜像定义:源二叉树 8 / 6 10 / \ / 5 7 9 11 镜像二叉树 8 / 10 6 / \ / 11 9 7 5 思路: 采用递归,每次递归前先将左右孩子调换,然后再对左右孩子进行递归。 代码实现: /** public class TreeNode { int ...原创 2019-07-13 11:51:52 · 156 阅读 · 0 评论 -
剑指Offer(18)-判断是不是子树
题目: 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) 思路: 这道题我们要注意的是,其是二叉树,而不是BST树。因此其节点可能会重复,也不会存在左边小,右边大的情况。因为我们再寻找子树的过程中,需要穷举,只要没有找到子树,那么我们就继续寻找root1和root2相同的根节点再去判断子树。 代码实现: /** public class TreeNode ...原创 2019-07-13 11:51:33 · 278 阅读 · 0 评论 -
剑指Offer(41)-和为s连续正数序列
题目1: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 思路: 查找两个数,我们直接想到了双指针法。因为是排序好的数组,两个指针最开始分别为数组起始角标l和末位角标r。计算两个角标和sum,如果sum大于s,那么r–,如果sun<s,那么l++。 至于最小乘积,a+b=s,a,b越远,乘积越小。 证明:若b&...原创 2019-06-18 17:18:07 · 247 阅读 · 0 评论 -
剑指Offer(40)-数组中只出现一次的数字
题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 题目: 本题主要考察的是异或,两个相同数异或的结果为0。这道题的低级版本是求除一个数字之外的所有数都是两个数字。根据异或的这一特性,我们将数组所有元素进行异或,那么结果就是单独的那个数。 现在我们需要得到两个数字,首先两个不同数字的异或结果肯定不为0。那么我们将所有元素异或后,得到的结果就是两个数...原创 2019-06-18 16:09:52 · 128 阅读 · 0 评论 -
剑指Offer(10_2)-判断两个整数的二进制数有多少位不同(异或)
题目: 输入两个整数m,n,计算需要改变m的二进制表示中的多少位才能得到n。 思路: 我们需要知道的是,二进制不是1就是0,而异或是只要对应二进制位不同此位就为1。因此异或后二进制数中1的个数则为其不同的二进制数位个数。 代码实现: public class Solution { public int NumberOf1(int n,int m) { int num=m^n...原创 2019-06-04 20:53:06 · 1212 阅读 · 0 评论 -
剑指Offer(30)-最小的K个数
题目: 输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。 方法一:使用快速排序寻找基准法 O(nlogn) 但是会改变原数组。 import java.util.ArrayList; public class Solution { private int partition(int[] array,int l,int...原创 2019-06-16 20:32:54 · 162 阅读 · 0 评论 -
剑指Offer(26)-复杂链表的复制
题目: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) 思路: 这道题难点主要在于random结点的复制上,因为random结点可能指向已经copy的前端结点,也有可能指向还未copy的后端结点。因此,如果我们想要处理random结...原创 2019-06-11 11:08:09 · 108 阅读 · 0 评论 -
剑指Offer(20)-顺时针打印矩阵
题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 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. 思路: 循环打印其实相当于打印一个个矩形,最开始从外圈矩形开始打印...原创 2019-06-08 09:22:42 · 119 阅读 · 0 评论 -
剑指Offer(17)-合并两个排序链表
题目: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 思路: 首先验证两个链表是否为空,确保不发生空指针异常。我们采用递归调用,每次递归我们只需要考虑当前两个结点的大小,并且只将小的结点返回给上一层递归,剩下的结点大小排序交给下一层递归去处理。 代码实现: /* public class ListNode { int val; Lis...原创 2019-06-07 09:50:22 · 174 阅读 · 0 评论 -
剑指Offer(16)-反转链表
题目: 输入一个链表,反转链表后,输出新链表的表头。 递归代码实现: 我们用递归做反转链表时,我们要思考当前结点需要做什么,首先判断结点为空,或者只有一个结点的情况。我们知道,返回时反转的是头结点。因此我们在调用的时候需要将其专门保存起来。当前结点如果还有下一个结点时,那么我们改变当前结点和下一个结点的关系,让下一个链表的next指向当前结点。因为每个结点的递归需要做的就是判断自己是不是尾结点,改...原创 2019-06-06 09:01:48 · 107 阅读 · 0 评论 -
剑指Offer(15)-链表中倒数第k个节点(O(N))
题目: 输入一个链表,输出该链表中倒数第k个结点。 思路: 我们采用双指针法pre.cur,让cur的指针先走k步,然后两个指针亦步亦趋走向末尾。我们会发现pre正好是倒数第k个结点。 代码实现: /* public class ListNode { int val; ListNode next = null; ListNode(int val) { th...原创 2019-06-05 20:50:09 · 104 阅读 · 0 评论 -
剑指Offer(14)-调整数组顺序使奇数位于偶数前面
题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 思路: 这道题原型是使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分。我们采用两个指针,一个指向前面,它只向后移动。一个指向后面,它指向前移动。当前面指针指向偶数并且后面指针指向奇数。那么我们就交换这两个数。...原创 2019-06-05 20:36:21 · 96 阅读 · 0 评论 -
剑指Offer(12)-打印1到最大的n位数(考虑溢出问题)
题目: 输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。 方法1: 首先计算出n位数的最大十进制数,然后从1进行打印。 代码实现: public class Solution { public void printToMaxOfNDigits(int n){ if(n<=0){ System.ou...原创 2019-06-05 16:35:32 · 235 阅读 · 0 评论 -
剑指Offer(11)-数值的整数次方;
题目: 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 思路: 这个题其实是很简单的,主要是考虑一些边界问题。首先考虑负数的问题,如果exponent是负数,那么进行标记并且将最后结果被1除。再者就是比较等于1还有0时,一定需要用equals比较,不要用== ,因为 ==只会比较到一定精度。 下来我们考虑如何求其expone...原创 2019-06-05 14:00:09 · 105 阅读 · 0 评论 -
剑指Offer(06)-两个栈实现一个队列
题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 思路: 栈的数据结构是先进后出,队列的数据结构是先进先出。那么我们将stack作为入队的存储空间,只要push我们就往stack1压入。那么当我们想取出元素时,我们将stack1的元素导入stack2中,stack2的栈顶元素就是我们要弹出的元素。 但此时,如果我们继续想push元素,我们必须将stack...原创 2019-05-30 21:23:14 · 200 阅读 · 0 评论 -
剑指Offer(05)-从尾到头打印链表
题目: 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。 思路: 从尾到头,那么我们应该想到先进后出的数据结构stack。这样我们就可以O(N)解决问题。 但是,我们需要知道的是,递归实际上也是栈结构,因此用递归也可以实现功能。 栈代码实现: /** * public class ListNode { * int val; * ListNode n...原创 2019-05-30 20:45:04 · 136 阅读 · 0 评论 -
剑指Offer(04)-替换空格
题目: 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 思路: java语言做这道题有现的工具方法,不再加以介绍。 代码实现1: public class Solution { public String replaceSpace(StringBuffer str) { ...原创 2019-05-30 20:19:39 · 233 阅读 · 0 评论 -
剑指Offer(42_2)-左旋字符串&右旋字符串
题目 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它! 思路: 左旋和右旋实际上是一样的。我们实际上可以采用翻转字符串来解决。左旋和右旋,实际上是把字符串分为...原创 2019-06-19 11:19:32 · 261 阅读 · 0 评论 -
剑指Offer(42_1)-翻转单词顺序
题目: 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么? 思路: 这道题依然需要使用...原创 2019-06-19 11:42:34 · 189 阅读 · 0 评论 -
剑指Offer(44)-扑克牌顺子
题目: 思路: 首先我们需要对牌进行排序,又因为赖子牌是0,因此在我们遍历的时候是可以先统计出赖子牌的数量的,然后我们对相邻两张牌进行处理,如果相等,直接返回false。若不相等,我们判断两张牌的点数,如果差1,那么是连牌,如果大于1,那么我们就用赖子牌进行替换,若赖子牌不够返回false。 import java.util.Arrays; public class Solution { ...原创 2019-06-19 12:09:34 · 227 阅读 · 0 评论