剑指Offer
SubaYasin
这个作者很懒,什么都没留下…
展开
-
【剑指offer】不用加减乘除做加法(Java解答)
题目描述写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。基本思路四则运算不能使用,那么就只能回归更本质的做:二进制运算。在分析二进制的运算前,我们先分析一下十进制的运算。例如,5+17=22,可以分三步进行,第一步只做加法,不进位,即5+17->12;第二步,做进位,5+7有一个进位,是10;第三步,将前两步的结果做一次加法,可得22,此时已经没有进位,...原创 2020-03-18 13:30:03 · 129 阅读 · 0 评论 -
【剑指offer】左旋转字符串(Java解答)
题目描述对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。基本思路首先定义“翻转字符串”为整个字符串从后往前读取。例如,“abcdef”翻转后为“fedcba”。对于字符串有特性:翻转两次之后,回到原顺序。利用这一特性,我们首先将字符串分为两部分:要放在后面的“abc”为第一部分...原创 2020-03-09 22:17:58 · 105 阅读 · 0 评论 -
【剑指offer】和为S的连续正数序列(Java解答)
题目描述输入一个正数 s,打印出所有和为 s 的连续正数序列(至少含有两个数)。基本思路由于是连续数字序列,那么我们只需要知道序列的头和为就知道序列中所有的数字。基于这一点,考虑用 start 和 end 表示序列的头和尾。此时通过以下方式移动两个指针:将 start 初始化为1,end 初始化为 2,curSum 初始化为3;当 curSum 小于 s 时,end 向前移动一位,然后...原创 2020-03-06 12:56:55 · 140 阅读 · 0 评论 -
【剑指offer】数组中只出现一次的数字(Java解答)
题目描述一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。基本思路首先我们考虑数组中只有一个出现一次的数字,其他的都出现两次,那么可以通过异或的方法,异或全数组结果就是那个只出现一次的数。现在数组中有两个只出现一次的数,自然就想到把数组分为两个部分,分别有一个数字就可以用上面的方法了。考虑异或全数组出现两次的数都已经被抵消了,剩下的两个数不一样,...原创 2020-03-01 15:48:05 · 155 阅读 · 0 评论 -
【剑指offer】平衡二叉树(Java解答)
题目描述输入一棵二叉树,判断该二叉树是否是平衡二叉树。基本思路通常来说,我们会想到从根节点开始向下,获取左右子树的深度(获取方法)进行比较。但这样做会重复计算底层节点,造成时间上的浪费。既然从上往下不行,那么就可以选择从下往上的递归方法,把深度信息交给底层计算,返回到上面来。在获取了深度信息之后,再比较左右子树深度的大小。该过程类似于后序遍历。具体解答过程如下:public boole...原创 2020-03-01 13:39:35 · 100 阅读 · 0 评论 -
【剑指offer】二叉树的深度(Java解答)
题目描述输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。基本思路基于后序遍历的方法,分别获取左右子树的深度,在回到父节点,从两个深度中选择大的一个加一返回。具体解法如下:public int TreeDepth(TreeNode root) { if (root == null) { retu...原创 2020-02-29 13:08:54 · 188 阅读 · 0 评论 -
【剑指offer】数字在排序数组中出现的次数(Java解答)
题目描述统计一个数字k在排序数组中出现的次数。基本思路由于是已排序的数组,所以可以通过二分法寻找到 k。而所有的 k 都是聚集在一起的,那么找到一个 k 就可以分别向左和向右搜索,就可以获取到 k 的范围了。以下为具体解答:public int GetNumberOfK(int [] array , int k) { int index = binarySearch(array,...原创 2020-02-29 12:53:41 · 132 阅读 · 0 评论 -
【剑指offer】第一个只出现一次的字符(Java解答)
题目描述在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).基本思路为了确定每个字符出现的次数和位置,我们是肯定需要遍历一次字符串的。现在的问题就是如何实现快速更新次数和位置数据。可以想到用HashMap的方式来保存数据,这样我们就可以在 O(1) 时间内更新了。由于全部是由字母...原创 2020-02-26 12:08:16 · 109 阅读 · 0 评论 -
【剑指offer】丑数(Java解答)
题目描述把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含质因子 7。 习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。基本思路所谓只有质因子 2、3、5,就是说所有的数都是由 2、3、5 乘出来的。那么我们可以通过空间换时间的方法,建立一个数组,把之前的数存下来,然后分别乘上 2、3、5 取最小...原创 2020-02-26 11:45:07 · 161 阅读 · 0 评论 -
【剑指offer】从1到n整数中1出现的次数(Java解答)
题目描述输入一个整数n,求1 ~ n这n个整数的十进制表示中1出现的次数。例如,输入12, 1~12这些整数中包含1的数字有1、10、11和12, 1一共出现了5次分析想要找到解答方法,必须先找到规律,不妨以21345为例进行分析。首先,把21345分为两段,1 ~ 1345和1345 ~ 21345。对于第二部分1345 ~ 21345,1 出现的次数的分析分为两种情况。首先分...原创 2020-02-25 14:49:54 · 185 阅读 · 0 评论 -
【剑指offer】连续子数组的最大和(Java解答,两种解释方案,一种解答过程)
题目描述输入一个整型数组,数组里有正数也有负数。数组中的一个或者连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。解法1:分析数组规律以数组{1, -2, 3, 10, -4, 7, 2, -5}为例,分析过程如下表。步骤操作累加子数组和最大的子数组和1加1112加-2-113抛弃-1,加3334加...原创 2020-02-24 13:52:53 · 123 阅读 · 0 评论 -
【剑指offer】最小的K个数(Java解答,O(n)和O(nlogk)两种解答)
题目描述输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。O(n)算法,需要修改输入的数组基本思路通过随机快排算法,将数组随机分为两个部分,若分割点在第 k 个数的左边,则继续随机分割比分割点大的部分,反之,随机分割较小的那部分。循环以上步骤,直至分割点就是第k个数。具体解答如下:public ArrayList&l...原创 2020-02-24 12:17:21 · 251 阅读 · 0 评论 -
【剑指offer】数组中出现次数超过一半的数字(Java解答)
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。一般解法 —— 以空间换时间基本思想通过HashMap存储每一个数组值出现的次数,直到找到超过一半的数字。具体解法如下:public int MoreThanHalfNu...原创 2020-02-22 17:23:41 · 159 阅读 · 0 评论 -
【剑指offer】字符串的排列(Java解答)
题目描述输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。基本思路按照排列组合的思想,所有的字符串的种类为Ann=n∗n−1∗...∗2∗1,其中n为字符串的长度A^n_n = n*n-1*...*2*1, 其中n为字符串的长度 Ann=n∗n−1∗...∗2∗1,...原创 2020-02-22 16:22:00 · 193 阅读 · 0 评论 -
【剑指offer】二叉搜索树与双向链表(Java解答)
题目描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。基本思路二叉搜索树的左右子树指针类似于双向链表的前后指针,而左子树就是都小于根节点,右子树都大于根节点。因此核心点就是找到子树转换后链表的最后一个节点然后与根节点进行对接。基本步骤为:处理左子树,获取左子树中链表的最后一个节点lastNode;将lastNode连...原创 2020-02-21 13:12:11 · 124 阅读 · 0 评论 -
【剑指offer】二叉树中和为某一值的路径(Java解答)
题目描述输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。基本思路通过遍历树的方式找到对应的路径,由于要先加入根节点,所以选用前序遍历。通过一个 stack 保存当前访问的路径,每次访问便压入栈中,访问结束(回到父节点)便将自己(栈顶)弹出。注意每次保存当前路径需要保存一个副本,否则会在运行...原创 2020-02-20 15:22:10 · 83 阅读 · 0 评论 -
【剑指offer】二叉搜索树的后序遍历序列(Java解答)
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。基本思路题干中有两个关键信息:二叉搜索树和后序遍历。二叉搜索树表示序列可以根据根节点的值分为两个部分:大于根节点和小于根节点。后序遍历表示序列的最后一个为根节点。结合上述两点即可判断序列是否是合法的。基本步骤为:根据根节点,将序列分出...原创 2020-02-20 13:16:31 · 139 阅读 · 0 评论 -
【剑指offer】从上往下打印二叉树(Java解答)
题目描述从上往下打印出二叉树的每个节点,同层节点从左至右打印。基本思路本题考查了对数据结构的熟悉程度。通过队列我们可以很方便地实现本题。具体操作:如果对列不为空,则获取并打印队列头,然后将队列头的左右非空子节点放入队列。重复该操作即可。以下为具体解答:public ArrayList<Integer> PrintFromTopToBottom(TreeNode roo...原创 2020-02-19 13:20:20 · 86 阅读 · 0 评论 -
【剑指offer】栈的压入、弹出序列(Java解答)
题目描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)基本思路首先按照压入顺序把数字压入栈中,同时比较弹出序列。如果下一个弹出的数字为...原创 2020-02-19 12:56:59 · 83 阅读 · 0 评论 -
【剑指offer】包含min函数的栈(Java解答,单栈和双栈解法)
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。分析本题的时间复杂度已经确定,那么算法优化就只能从空间复杂度下手,一般来说采用辅助栈保存当前最小值是一个通用解法,这样就需要两个栈。同样我们可以改变栈中保存值,来实现单栈解法。辅助栈解法思路很简单,采用一个数据栈保存数据,一个辅助栈保存当前状态下的最小值。步骤操作数...原创 2020-02-18 15:41:43 · 175 阅读 · 0 评论 -
【剑指offer】顺时针打印矩阵(Java解答)
题目描述输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.解答0思路对于这种一下看不出解答的复杂问题,但却是某种具体过程,可以通过图形来帮助思考。首先我们定义一个坐标系,...原创 2020-02-18 15:08:08 · 180 阅读 · 0 评论 -
【剑指offer】二叉树的镜像(Java的递归和循环解法)
题目描述操作给定的二叉树,将其变换为源二叉树的镜像。核心本题的核心点就是想办法遍历所有的节点,同时反转各个节点的左右子节点。递归解法基本思路通过递归到达叶节点,然后从下往上将每个节点的左右子节点互换。递归解法代码简洁,是通常给出的解法。但递归解法会消耗更多的堆栈,因此在此也给出了对应的循环解法。以下为解答:public void Mirror(TreeNode root) {...原创 2020-02-17 12:41:49 · 124 阅读 · 0 评论 -
【剑指offer】数的子结构(Java解答)
题目描述输入两棵二叉树A,B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)基本思路1、在A中查找与B树根节点值相同的节点M。若相同,则判断以M节点为根的树与B树是否相同。若相同,则递归返回true;若不相同,则继续判断M节点左右子树中是否有相同的根节点。若不相同,则继续在左右子树中递归寻找。2、判断树是否相同的方法:通过递归法,子树相同,根节点相同,则树相同。以下为...原创 2020-02-17 12:10:47 · 132 阅读 · 0 评论 -
【剑指offer】合并两个排序链表(Java解答)
题目描述输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。基本思路首先分析合并两个链表的过程。比较两个链表的头指针,将较小值作为合并后链表的头结点,然后继续合并两个链表中的剩余节点。由于两个链表都是单调递增的,所以接下来只需要循环操作第一步到尾部即可,因此我们可以采用递归的方法实现该循环。注意对两个链表中有空指针的情况的分析:只要有一个为空指针...原创 2020-02-16 13:05:22 · 559 阅读 · 0 评论 -
【剑指offer】反转链表(Java解答)
题目描述输入一个链表,反转链表后,输出新链表的表头。基本思路两个指针一个指向当前处理节点cur,一个指向上一个节点pre,每次将cur的next指针指向pre即可。Tips:指针失效前都要考虑是否要把原值保存,如cur的next指针每次改变前都需要保存原来的值。以下为解答:public ListNode ReverseList(ListNode head) { ListNo...原创 2020-02-16 12:21:20 · 117 阅读 · 0 评论 -
【剑指offer】链表中倒数第k个结点(Java解答)
题目描述输入一个链表,输出该链表中倒数第k个结点。核心思路:双指针法,提前设置好两个距离为k的指针,同时移动到尾部,前面的指针就是倒数第k个节点。复杂度: O(n)思路很简单,但是对于指针类的编程要注意代码的鲁棒性,在任何输入都不能使得代码崩溃。以下三点尤其要注意:输入的head为空指针,要避免滴啊发访问空指针。输入的链表节点总数少于k,前置指针需要先移动k-1步,会发生空指针访...原创 2020-02-15 14:49:41 · 270 阅读 · 0 评论 -
【剑指offer】数值的整数次方(Java解答)
基本思路:为了提高效率,计算指数可以通过以下公式进行递归:an={an/2⋅an/2n为偶数a(n−1)/2⋅a(n−1)/2⋅an为奇数{{\text{a}}^{n}}=\left\{ \begin{matrix} {{\text{a}}^{n/2}}\cdot {{\text{a}}^{n/2}} & \text{n}为偶数 \\ {{\text{a}}^{(n-1...原创 2020-02-14 14:26:37 · 101 阅读 · 0 评论 -
【剑指offer】二进制数中的1(Java的两种解答)
常规解法通常我们会通过反复左移实现,这样32位整数需要循环32次。对于右移的特殊说明:对于负数,算数右移(>>)会出现死循环,需要使用逻辑右移(>>>)。以下为解答:private int NumberOf1(int n) { int count = 0; int flag = 1; while (flag != 0) { ...原创 2020-02-14 12:55:12 · 152 阅读 · 0 评论 -
【剑指offer】旋转数组的最小数字(Java解答)
本题基本思路是通过二分查找缩小范围,start指针一直在前面的递增数组中向前移动,end指针一直在后面的递增数组中向后移动,最后两者相差1的时候,就是end指针指向最小值的时候。但要考虑两种特殊情况:1、数组旋转0个,即此时已经是有序数组,应该直接返回第一个数,因此,mid初始化为0;2、start\min\end指针都指向相同的数字,那么我们就没有办法知道往哪个方向移动,此时只能遍历...原创 2020-02-12 13:03:12 · 270 阅读 · 0 评论 -
【剑指offer】斐波那契数列(Java解答)
本题一般思路是递归,但是普通递归方法会重复计算大量的数值,不是很有效率。而一般能用递归求解可以考虑使用循环方式。本题发现结果之和前面两个数有关,所以循环时保存前面两个数即可。以下为解答:public int Fibonacci(int n) { int[] result = {0, 1}; if (n <= 1) { return result[n]; ...原创 2020-02-13 12:46:09 · 129 阅读 · 0 评论