
剑指Offer
文章平均质量分 61
一刷剑指Offer
炫酷的伊莉娜
C/C++领域新星创作者、阿里云专家博主、入围2023年博客之星。大学本科在读,计算机科学与技术专业,致力于C/C++方向的学习。一步一个脚印,查漏补缺,努力提升自己,记录学习过程。
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
【一刷《剑指Offer》】面试题 50(案例):树中两个结点的最低公共祖先
由此可以写出递归代码,直到 p、q 既不同时大于 root,也不同时小于 root,则 root 就是 p、q 的最近公共祖先,返回 root。从上往下遍历,判断根结点是否匹配两个节点之一。如果是,则根结点就是最低祖先,否则往下递归遍历左右子树。题目要求从根结点为 root 的树返回 p、q 的最近公共祖先,使用递归。原创 2024-07-21 12:39:11 · 343 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 49(案例):把字符串转换成整数
题目要求返回的数值范围应在 [−2^31, 2^(31−1)] ,因此需要考虑数字越界问题。而由于题目指出 环境只能存储 32 位大小的有符号整数 ,因此判断数字越界时,要始终保持 res 在 int 类型的取值范围内。在每轮数字拼接前,判断 res 在此轮拼接后是否超过 INT_MAX(2147483647),若超过则加上符号位直接返回。原创 2024-07-21 12:35:38 · 323 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 48:不能被继承的类
《剑指Offer》对应内容:可参考:【C++】继承 -- 详解_c++,两个派生类继承一个基类,声明对象的时候用基类的对象。-优快云博客原创 2024-07-21 12:10:13 · 142 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 47:不用加减乘除做加法
不使用新的变量,交换两个变量的值。比如有两个变量 a、b,我们希望交换它们的值。补码的优势:加减法可以统一处理(CPU 只有加法器)。因此,以上方法同时适用于正数和负数的加法。在计算机系统中,数值一律用。原创 2024-07-21 12:07:09 · 257 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 46:求 1+2+...+n
在 Solution 类中,通过 mechanicalAccumulator 方法控制累加器的行为:首先重置累加器的状态,然后创建一定数量的 Temp 对象,最后返回累加器累计的结果。通常实现递归的时候我们都会利用条件判断语句来决定递归的出口,但由于题目的限制我们不能使用条件判断语句,那么我们就要选择使用别的办法来确定递归出口 —— 逻辑运算符的短路性质。上面书中讲到的第四种方法在这里无法实现,因为题目的 n 是动态的,所以无法使用模板类型求解。原创 2024-07-21 11:31:28 · 224 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 45:圆圈中最后剩下的数字
【代码】【一刷《剑指Offer》】面试题 45:圆圈中最后剩下的数字。原创 2024-07-21 10:57:08 · 215 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 44:扑克牌的顺子
因此,可以将问题转化为:这 5 个朝代是否满足以上两个条件?根据题意,这 5 个扑克牌对应的数字连续的。原创 2024-07-21 10:43:31 · 276 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 43:n 个骰子的点数
所以最终需要返回的浮点数组的内容就会是这个样子:[#n / pow(6.0, n), #(n + 1) / pow(6.0, n), #(n + 2) / pow(6.0, n), ..., #6n / pow(6.0, n)]。投掷 n 个骰子,那么就会有 n 个面朝上,这 n 个朝上的面的点数之和 s 的最大值是 6*n,最小值是 n。:假如只有一个骰子(n=1),s 的范围是 [n, 6n],所以 s 的范围是 [1, 6],且 s 的每个值可能出现的次数都为 1。,k 属于 [1, 6]。原创 2024-07-21 10:26:58 · 313 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 42:翻转单词顺序 VS 左旋转字符串
思考一下,将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了。不要使用辅助空间,空间复杂度要求为O(1)。不能使用辅助空间之后,那么只能在原字符串上下功夫了。保存第一个,剩下的整体前移一个,第一个放在最后,完成一次移动,一次能移动,多次也可以。举个例子,源字符串为:"the sky is blue "字符串反转:"eulb si yks eht"单词反转:"blue is sky the"(3)思路三(双倍字符串,不推荐)(2)思路二(逆置)原创 2024-07-21 08:50:31 · 443 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 41:和为 s 的两个数字 VS 和为 s 的连续正数序列
注意,代码中只给你你目标和,其实隐含条件就是序列最大值不会大于该值,而且要连续,这也是细节。初始化:双指针 left,right 分别指向数组 price 的左右两端。计算和:sum=price[left]+price[right];若循环结束,则返回空数组,代表无和为 target 的数字组合。的思想进行解决,这种方式可以说很优秀了。循环搜索:当双指针相遇时跳出。原创 2024-07-21 08:48:50 · 298 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 40:数组中只出现一次的数字
分组的结果一定是:相同数据被分到了同一组,不同数据一定被分到了不同的组就将问题就转化成了两个上面的问题。时,我们把数组中所有的数依次异或运算,最后剩下的就是落单的数,因为成对儿出现的数都相互抵消了。然后把这两个组按照最开始的思路,依次异或,剩余的两个结果就是这两个只出现一次的数字。如果只有一个数据单独出现,直接整体异或可以得到结果。我们就取第一个 1 所在的位数,假设是第 3 位,接着把原数组分成。,首先可以采取先整体异或,异或结果一定不为 0(,因为相同数字所有位都相同,而不同的数。(假设是A 和 B)原创 2024-07-21 08:46:37 · 337 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 39:二叉树的深度
明确单层递归的逻辑:如何判断当前传入节点为根节点的二叉树是否是平衡二叉树呢,当然是左子树高度和右子树高度相差。分别求出左右子树的高度,然后如果差值小于等于 1,则返回当前二叉树的高度,否则则返回 -1,表示已经不是二叉树了。这道题题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。而根节点的高度就是二叉树的最大深度,所以这道题我们通过后序求的根节点高度来求的二叉树最大深度。在二叉树中,一层一层的来遍历二叉树,记录一下遍历的层数就是二叉树的深度。原创 2024-07-21 08:45:36 · 451 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 38:数字在排序数组中出现的次数
二分查找中,寻找 st 即为在数组中寻找第一个大于等于 target 的下标,寻找 right 即为在数组中寻找第一个大于 target 的下标,然后将其下标减一。两者的判断条件不同,所以在二分的时候要注意判断条件。用两个变量记录第一次和最后一次遇见 target 的下标,但这个方法的时间复杂度为 O(n),没有利用到数组升序排列的这个条件。(记为 right)。当 target 在数组中存在时,target 在数组中出现的次数为。考虑 target 在数组中出现的次数,其实我们要找的就是数组中。原创 2024-07-21 08:44:26 · 244 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 37:两个链表的第一个公共结点
如果把图 5.3 逆时针旋转 90°,我们就会发现两个链表的拓扑形状和一棵树的形状非常相似,只是这里的指针是从叶结点指向根节点的。两个链表的第一个公共结点正好就是二叉树中两个叶节点的最低公共祖先。,后面大家的步调一致,往后找第一个地址相同的节点,就是题目要求的节点,所以需要各自遍历两次链表。题目要求是单链表,所以如果有交点,则最后一个链表的节点地址一定是相同的。让长的链表先走 abs(length1-length2) 步。求第一公共节点,本质是。原创 2024-07-21 08:23:30 · 361 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 36:数组中的逆序对
【代码】【一刷《剑指Offer》】面试题 36:数组中的逆序对。原创 2024-07-21 08:19:00 · 220 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 35:第一个只出现一次的字符
如果需要判断多个字符是不是在某个字符串里出现过或者统计多个字符在某个字符串中出现的次数,我们可以考虑基于数组创建一个简单的哈希表,这样可以用很小的空间消耗换来时间效率的提升。例如从第一个字符串 "We are students." 中删除在第二个字符串 "aeiou" 中出现过的字符得到的结果是 "W r stdnts."。问题:在英语中,如果两个单词中出现的字母相同,并且每个字母出现的次数也相同,那么这两个单词互为变位词(Anagram)。问题:定义一个函数,删除字符串中所有重复出现的字符。原创 2024-07-20 21:20:46 · 875 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 34:丑数
根据题意,每个丑数都可以由其他较小的丑数通过乘以 2 或 3 或 5 得到。所以,我们可以考虑使用一个优先队列保存所有的丑数,每次取出最小的那个,然后乘以 2 , 3 , 5 后放回队列。然而,这样做会出现重复的丑数。为了避免重复,我们可以用三个指针 p2、p3、p5 来分别表示下一个丑数是当前指针指向的丑数乘以 2、3、5。原创 2024-07-20 20:20:46 · 286 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 33:把数组排成最小的数
我们将说法换一下,对于本题而言,我们要的有效序列是:序列中任何一个元素 y,和它前的任何一个元素 x 进行有序组合形成 xy,比和他后面的任何一个元素z进行有效序列组合 yz,满足条件 xy < yz(采用字典序列排序),如 {32,31},有效组合是 3132,所以我们拍完序列之后序列变成 {31,32}。可以采用字符串来表示数字,这样就能简洁地解决大数问题。这道题的核心理解是对于排序算法的理解。通常我们所理解的排序是比较大小的,比如:升序排序的序列意思是:序列中任何一个数字都比前面的小,比后面的大。原创 2024-07-20 19:58:24 · 365 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 32:从 1 到 n 整数中 1 出现的次数
10个数会出现 1, 那么有多少个 这样的数呢?有 34 个 这样的数 加 十位为 1的十个数 即 34 * 10 + 10。什么时候个位会出现 1 呢,当然只有一种可能,那就是 1 ,那么有多少个 个位 为 1的数呢?有342个 加 1(这个 1 为 数字 1) 即 342 * 1 + 1个。那就只有 0 * 1000 个了,因为千位为 0 , 很显然最高为不可能为零。以此类推,会有 0 * 1000 加上 千位为 1 的个数 即 0 * 100 + 1000。那就有 342 个个位为 1 的数。原创 2024-07-20 19:56:55 · 212 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 31:连续子数组的最大和
状态递推:dp[i] = max(dp[i-1]+array[i], array[i]) 【状态的初始化:dp[0] = array[0], max = array[0]从前往后迭代,一个个数字加过去,如果 sum原创 2024-06-02 17:57:03 · 373 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 30:最小的 k 个数
用一个大根堆实时维护数组的前 k 小的值。首先将前 k 个数插入大根堆中,随后从第 k+1 个数开始遍历,如果当前遍历到的数比大根堆的堆顶的数要小,就把堆顶的数弹出,再插入当前遍历到的数。如果面试时遇到的面试题有多种解法,并且每个解法都各有优缺点,那么要向面试官问清楚题目的要求,输入的特点,从而选择最合适的解法。最小堆(小根堆):树中每个非叶子结点都不大于其左右孩子结点的值,也就是根节点最小的堆。最大堆(大根堆):树中每个非叶子结点大于其左右孩子结点的值,也就是根节点最大的堆。1、排序(O(NlogN))原创 2024-06-02 17:28:56 · 491 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 29:数组中出现次数超过一半的数字
如果剩下两个,那么这两个也是一样的,就是我们要找的结果,在其基础上把最后剩下的一个数字或者两个作为我们的 target 再回到原来数组中,这里找到的题目链接所对应的数据都满足数组是非空的,并且给定的数组总是存在多数元素。所以下面就不再另外判断了。思路三:目标条件:目标数据超过数组长度的一半。,然后检测中间出现的数字出现的次数是否符合要求。将数组遍历一遍统计一下数字出现次数进行最终判断。同时去掉两个不同的数字,到最后剩下的一个数就是。出现次数最多的数字一定在中间位置。统计每个字符出现的次数。原创 2024-06-02 17:28:30 · 415 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 28:字符串的排列
这相当于先得到 a1、a2、a3、a4、a5、a6、a7 和 a8 这 8 个数字的所有排列,然后判断有没有某一个的排列符合题目给定的条件,即 a1+a2+a3+a4==a5+a6+a7+a8,a1+a3+a5+a7==a2+a4+a6+a8,并且 a1+a2+a5+a6==a3+a4+a7+a8。输入一个含有 8 个数字的数组,判断有没有可能把这 8 个数字分别放到正方体的 8 个顶点上(如图 4.15 所示),使得正方体上三组相对的面上的 4 个顶点的和都相等。第二部分:剩下的是子问题。原创 2024-06-02 17:21:27 · 478 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 27:二叉搜索树与双向链表
上面力扣上的这道题目和牛客上的不太一样,力扣上的是双向循环链表,而牛客上的并不是循环链表,所以返回的是头结点。原创 2024-06-02 16:53:30 · 322 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 26:复杂链表的复制
【代码】【一刷《剑指Offer》】面试题 26:复杂链表的复制。原创 2024-06-02 16:06:30 · 228 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 25:二叉树中和为某一值的路径
在判定现有结果是否满足条件(待选结果是否符合条件,是的话就添加结果集)回溯的算法,回溯法本质是一个基于 DFS。先添加值(待选结果)原创 2024-05-28 15:49:16 · 204 阅读 · 1 评论 -
【一刷《剑指Offer》】面试题 24:二叉搜索树的后序遍历系列
如果是要求处理一颗二叉树的遍历序列,我们可以先找到二叉树的根节点,再基于根结点把整棵树的遍历序列拆分成左子树对应的子序列和右子树对应的子序列,接下来再递归地处理这两个子序列。这和前面问题的后序遍历很类似,只是在前序遍历得到的序列中,第一个数字是根节点的值。若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值。若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。节点),如果去掉最后一个元素的序列为 T,那么。的后序序列的合法序列是,对于一个序列。,且这两段(子树)都是合法的后序序列。原创 2024-05-27 21:18:06 · 429 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
接下来每一次从队列的头部取出一个结点,遍历这个结点之后把从它能到达的结点(对树而言是子结点)都依次放入队列。核心思路:当前层从左向右遍历,那么下层就从 left 到 right 入栈,当前层如果从右向左遍历,那么下层就从 right 到 left 入栈。之字形打印的本质也是对树形结构的层序遍历,不过在遍历的过程中,需要更改遍历顺序,可以采用 stack 和 queue 的方式来进行处理。树是图的一种特殊退化形式,从上到下按层遍历二叉树,从本质上来说是广度优先遍历二叉树。本质是层序遍历二叉树,借助。原创 2024-05-21 20:28:34 · 461 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
要判定第二个序列是否可能是该栈的弹出序列,就要使用指定的入栈顺序模拟出来对应的弹栈序列,我们设入栈顺序序列式 pushV,可能出栈序列。遍历入栈序列,只要 popv 的第一个数据和当前 pushv 的数据不相等,一直进行入栈操作。最后在循环这个过程,如果符合要求,最后栈结构一定是空的。而我们的入栈顺序是一定的,也就决定了,我们必须一直入栈,直到碰到 popv。只要 st 栈顶值和 popv 的出栈序列数据是相等的,则一直执行出战逻辑。的第一个元素,一定是最后入栈,最先弹栈的,返回 st.empty()原创 2024-05-21 12:52:56 · 291 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
但是,面试官很容易就会问到:如果想拿出第二小,第三小的值怎么拿?题面说了,保证测试中不会当栈为空的时候,对栈调用 pop()这时再用上面的办法就不行了。所以,后面的代码对空的检验可有可无。这里是为了实现算法, 所以就不从。变量,每次更新的时候,都对。辅助栈内部元素可能会出现 “很容易想到,在栈内部保存。原创 2024-05-20 15:33:41 · 198 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
对于每层,从左上方开始以顺时针的顺序遍历所有元素。遍历完当前层的元素之后,将 left 和 top 分别增加 1,将 right 和 bottom 分别减少 1,进入下一层继续遍历,直到遍历完所有元素为止。可以将矩阵看成若干层,首先输出最外层的元素,其次输出次外层的元素,直到输出最内层的元素。定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。原创 2024-05-20 15:28:28 · 466 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 19:二叉树的镜像
这是一道很经典的二叉树问题。显然,我们从根节点开始,递归地对树进行遍历,并从叶子节点先开始翻转。如果当前遍历到的节点 root 的左右两棵子树都已经翻转,那么我们只需要交换两棵子树的位置,即可完成以 root 为根节点的整棵子树的翻转。操作给定的二叉树,将其变换为源二叉树的镜像。仔细观察可以发现,所谓的二叉树镜像本质是自顶向下(或。其实就是 2、迭代法中用到的层序遍历,这里就没有用到递归,而是利用队列先进先出的性质来实现的。进行左右子树交换的过程。原创 2024-05-13 18:35:03 · 218 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 18:树的子结构
首先明白:子结构怎么理解,可以理解成子结构是原树的子树(或者一部分)。也就是说,B 要是 A 的子结构,那么 B 的根节点+左子树+右子树都得在 A 中存在且构成树形结构。二叉树都是递归定义的,所以递归操作是比较常见的做法。在确定从该位置开始,在比较其左右子树的内容是否一致。先确定比较的起始位置。原创 2024-05-12 19:34:21 · 294 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
可以选择一个一个节点的归并。可以采用递归来完成。原创 2024-05-10 13:55:40 · 222 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 16:反转链表
需要注意的是 n_1 的下一个节点必须指向 ∅。如果忽略了这一点,链表中可能会产生环。假设链表为:n_1→…→n_k−1→n_k→n_k+1→…若从节点 n_k+1 到 n_m 已经被反转,而我们正处于 n_k。我们希望 n_k+1 的下一个节点指向 n_k。所以,n_k->next->next=n_k。,整体右移,边移动,边翻转,保证不会断链。原创 2024-05-07 18:41:38 · 544 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点
为了解决这个问题,我们也可以向上面那道题一样定义一个 fast 和 slow 指针,同时从链表的头结点出发,slow 指针一次走一步,fast 指针一次走两步。当 fast 指针走到链表的末尾时,slow 指针正好在链表的中间。可以定义两个指针(快慢双指针),fast 指针先走 k 步,再让 slow 指针跟在后面,使用 “前后指针” 的方式,当 fast 指针到达结尾,这道题也一样,定义两个指针 fast 和 slow,同时从链表的头结点出发,slow 指针一次走一步,fast 指针一次走两步。原创 2024-05-06 19:03:23 · 553 阅读 · 2 评论 -
【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面
让 left 往后遍历,直到找到前半部分的第一个偶数,让 right 向前遍历,直到找到后半部分的第一个奇数,然后交换 left 和 right 所在位置的数。左向右遍历,每次遇到的都是最前面的奇数,将该奇数之前的内容(偶数序列)整体后移一个位置,腾出位置后,将奇数保存在它将来该在的位置。:假设现在新增需求,需要保证奇数和奇数,偶数和偶数之间的相对位置不变。,因为我们是从左往右放的,没有跨越奇数,所以一定是相对位置不变的。按照题目意思,其实跟快排的思路一致,我们只需要定义。原创 2024-05-05 09:49:22 · 304 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 13:在 O(1) 时间删除链表结点
一般来讲,正常的解法时间复杂度都是 O(N),因为我们要找到待删除节点,不得不牺牲 O(N) 的时间复杂度。这就是这道题目有意思的地方,如果删除节点为前面的 n−1 个节点,时间复杂度均为 O(1),只有删除节点为最后一个的时候,时间复杂度才会变成 O(n)。之前的三种方法都需考虑头节点是否是待删除的节点,并且删除头节点的代码逻辑与删除非头节点的特别相似,可通过在头节点前面增加虚拟头节点,避免单独将拎头节点出来考虑,但是需要注意:返回的是虚拟头节点的下一节点而不是虚拟头节点。:头节点可能是待删除的节点。原创 2024-05-05 09:48:13 · 538 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 12:打印 1 到最大的 n 位数
由于没有限定输入两个数的大小范围,我们也要把它当作大数来处理。在第一个思路中,实现了在字符串表示的数字上加 1 的功能,可以参考这个思路实现两个数字的相加功能。原创 2024-05-05 09:47:28 · 903 阅读 · 0 评论 -
【一刷《剑指Offer》】面试题 11:数值的整数次方
从 x 开始,每次直接把上一次的结果进行平方,计算 6 次就可以得到 x^64 的值,而不需要对 x 乘 63 次 x。当指数 n 为负数时,我们可以计算 x^(−n) 再取倒数得到结果,因此我们只需要考虑 n 为自然数的情况。这些步骤中,我们把上一次的结果进行平方后,还要额外乘一个 x。这些步骤中,我们直接把上一次的结果进行平方,而在。由于每次递归都会使得指数减少一半,因此递归的层数为。,算法可以在很快的时间内得到结果。原创 2024-04-30 16:50:26 · 527 阅读 · 3 评论