自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(72)
  • 收藏
  • 关注

原创 代码随想录day30(2)回溯:组合(leetcode77)

思路:首先定义两个变量,一个存放符合条件的单一结果,另一个存放符合条件结果的集合,for循环用来横向遍历,递归用来纵向遍历,别忘记pop弹出,注意剪枝优化。题目要求:给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

2024-03-25 21:50:27 218

原创 代码随想录day30(1)二叉树:把二叉搜索树转换为累加树(leetcode538)

题目要求:给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。思路:对于二叉搜索树来说,其中序遍历是有序的,所以如果我们想实现累加树,反中序遍历即可,也就是右中左遍历,此时就是由大到小遍历,我们再使用两个指针即可实现。

2024-03-25 21:21:54 161

原创 代码随想录day29(2)二叉树:将有序数组转换为二叉搜索树(leetcode108)

思路:思路比较简单,如果目标是平衡二叉树,我们每次只需要取数组的中间元素作为根节点,分成左右两个子树,再递归地进行划分即可,注意区间的开闭要一致。题目要求:将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

2024-03-23 11:59:59 187

原创 代码随想录day29(1)二叉树:修剪二叉搜索树(leetcode669)

思路:首先有一个误区,如果一个节点不在所要求的区间内,不能直接把它与它的左右子树删除。如给定区间[5, 10],即使节点为3,它的右子树大于3,有可能在区间内,仍满足条件。所以不满足情况时只能删除本节点和一侧子树,然后继续判断另一侧子树是否满足要求。注意递归法内的返回值与调用过程,有一点绕。题目要求:给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L)。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。

2024-03-23 08:35:27 290

原创 代码随想录day28(2)二叉树:删除二叉搜索树中的节点(leetcode450)

题目要求:给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。3.左右孩子均不空,此时应该将删除节点的左孩子(或右孩子)放到删除节点的右子树最左节点的左孩子上(左子树最右节点的右孩子上)思路:首先要删除二叉搜索树中的节点,第一步就是找到此节点,如果遍历到空就直接返回。2.左子树不空右子树空(或左子树空右子树不空),删除节点,将其左孩子(右孩子)进行补位。

2024-03-22 10:15:40 248

原创 代码随想录day28(1)二叉树:二叉搜索树中的插入操作(leetcode701)

思路:对于二叉搜索树来说,我们每次插入都可以在叶子节点处插入,也无需调整左右子树高度,比较简单。本题没有通过递归函数返回节点,而是通过递归函数的返回值完成父子节点赋值,更加简洁。题目要求:给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。返回插入后二叉搜索树的根节点。输入数据保证,新值和原始二叉搜索树中的任意节点值都不同。

2024-03-22 09:48:15 266

原创 代码随想录day27(1)二叉树:二叉树的最近公共祖先(leetcode236)

思路:首先遍历顺序应为后序,因为判断两个节点的最近公共祖先实际上要自底向上,可以通过回溯来实现。实际上包含两种情况:第一种是节点p本身有一个子孙节点q,另一种就是没有此关系的情况,但实际上解决第二种情况的同时也解决了第一种情况。题目要求:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

2024-03-21 13:49:38 125

原创 代码随想录day27(2)二叉树:二叉搜索树的最近公共祖先(leetcode235)

思路:与普通二叉树的公共祖先问题相比,二叉搜索树由于其自身特点,过程会比较简单。如果root大于这两个指定节点,说明其最近公共祖先一定在root左子树中;同理root小于这两个指定节点,最近公共祖先一定在其右子树中;如果root的大小在这两个节点之间,说明root就是最近公共祖先(从root开始分开),所以按这个过程使用迭代法会非常简单,但递归法同样可以实现。题目要求:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

2024-03-21 09:24:24 213

原创 代码随想录day26(2)二叉树:二叉搜索树中的众数(leetcode501)

思路:如果不考虑二叉搜索树,我们可以遍历每个节点,用map去统计频率,再将map转换成为vector进行排序即可(使用pair)。但作为二叉搜索树,其中序遍历有序,我们只需要比较相邻两个元素是否相同,记录元素个数,注意更新maxCount,这样我们只需要遍历一次,而不需要先遍历一次记录maxCount,再遍历取元素。题目要求:给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数。结点左子树中所含结点的值小于等于当前结点的值,结点右子树中所含结点的值大于等于当前结点的值。

2024-03-20 13:34:28 191

原创 代码随想录day26(1)二叉树:二叉搜索树的最小绝对差(leetcode530)

思路:最简单的想法就是新建数组,通过中序遍历将节点值全都存入数组中(有序),然后计算相邻两节点的最小值。题目要求:给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

2024-03-20 11:05:24 143

原创 代码随想录day25(2)二叉树:验证二叉搜索树(leetcode98)

思路:首先对于二叉搜索树,它的中序遍历是有序的。最简单的想法就是将二叉搜索树转成一个数组,验证数组是否有序就可以(二叉搜索树中没有重复元素)。也可以不新建数组,直接在树上进行操作,但注意二叉搜索树的定义,左子树节点都小于中间节点,右子树都大于中间节点,可以通过双指针法进行优化。题目要求:给定一个二叉树,判断其是否是一个有效的二叉搜索树。

2024-03-19 13:03:08 424

原创 代码随想录day25(1)二叉树:二叉搜索树中的搜索(leetcode700)

思路:本题思路比较简单,由于二叉搜索树的特性,只需要比较当前节点与val的大小即可,如果大于就去左子树搜索,小于就去右子树搜索,直到搜索到或者到叶子节点。注意递归法需要一个res去存储返回的节点。题目要求:给定二叉搜索树(BST)的根节点和一个值。你需要在BST中找到节点值等于给定值的节点。返回以该节点为根的子树。如果节点不存在,则返回 NULL。

2024-03-18 21:58:32 363

原创 代码随想录day24(2)二叉树:合并二叉树(leetcode617)

思路:如果使用迭代法,就是通过层序遍历,通过队列进行判断进行相加。如果使用递归法,代码比较简单,如果有一棵树为空,另一棵就覆盖,如果两个都不为空,就相加后将值放在t1中,递归处理左右子树即可。题目要求:将两个二叉树合并,要求是将同位置处的两个节点值相加,如果一个为空那就将另一个二叉树的值覆盖。

2024-03-18 11:39:53 384

原创 代码随想录day24(1)二叉树:最大二叉树(leetcode654)

思路:使用前序遍历,在数组中遍历到最大的节点,将数组分为左右两个部分,递归地进行处理左右区间构造二叉树即可。也可以不用定义新的数组,在原数组上通过下标索引直接操作。给定一个不含重复元素的整数数组。通过给定的数组构建最大二叉树,并且输出这个树的根节点。

2024-03-18 11:18:33 412

原创 代码随想录day23(2)二叉树:从中序与后序遍历序列构造二叉树(leetcode106)

思路:408的经典题目,思路和手撕的思路差不多,先从后序中找到根节点,再从中序中找到此节点,然后分割成左右子树,记录一下左右子树的节点个数,再在后序中切割,继续递归处理即可。2.如果不为空,那么取后序数组最后一个元素作为节点元素。题目要求:根据一棵树的中序遍历与后序遍历构造二叉树。1.数组大小为零的话,说明是空节点了。3.在中序中找到此节点,开始分割。4.分割中序数组,分为左右子树。5.分割后续数组,分为左右子树。

2024-03-17 20:22:45 636

原创 代码随想录day23(1)二叉树:路径总和(leetcode112)

思路:可以采用深度优先搜索的方法,设置一个count为目标值,每次访问节点的时候count就减去node->val,遍历到叶子节点的时候判断count是否为0。稍微注意一下回溯过程即可,最后传入值时应该减去根节点的val!题目要求:给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

2024-03-17 17:43:39 404

原创 代码随想录day22(2)二叉树:找树左下角的值(leetcode513)

思路:本题要找到树最后一行最左边的值。如果使用递归法,我们需要先找到最后一行,也即是找到深度最深的叶子节点;对于最左边的节点,我们优先从左侧递归即可。对于本题来说,使用非递归的层序遍历更容易一些。题目要求:找到树左下角的值。

2024-03-16 14:46:10 435

原创 代码随想录day22(1)二叉树:左叶子之和(leetcode404)

思路:本题应该满足两个条件,一是叶子节点,二是要求是左叶子。所以判断时,如果一个节点左孩子的左右孩子均为空,且其右孩子也为空,此节点的左孩子就为左叶子节点。题目要求:计算二叉树所有左叶子之和。

2024-03-16 12:11:52 385

原创 代码随想录day21(2)二叉树:二叉树的所有路径(leetcode257)

思路:我们先递归地进行前序遍历,同时要注意回溯的过程,注意一些库的用法即可。题目要求:按任意顺序返回所有从根节点到叶节点的路径。

2024-03-15 13:18:27 363

原创 代码随想录day21(1)二叉树:平衡二叉树(leetcode110)

思路:递归地比较左右子树,只要有一棵子树不满足条件就说明这棵树不是平衡二叉树。本题采用迭代法较为复杂。题目要求:判断一棵树是否为平衡二叉树。

2024-03-15 12:59:55 373

原创 代码随想录day20(2)二叉树:完全二叉树节点个数(leetcode222)

但是对于完全二叉树来说,只有最底层右侧的节点可能没满,其余每层节点都达到了最大值。所以我们可以向左、向右一直遍历,如果两个遍历深度相等,说明这是满二叉树;如果不相等,递归地去遍历左右子树,因为单个节点也是满二叉树。思路:首先完全二叉树可以用普通二叉树的方法来求,但是需要遍历所有的节点。题目要求:求一个完全二叉树的节点个数。

2024-03-14 19:55:50 443

原创 代码随想录day20(1)二叉树:二叉树的最小深度(leetcode111)

思路:最小深度指的是从根节点到最近叶子节点的最短路径上的节点数量(左右孩子必须都为空!思路类似于求二叉树的最大深度,仍然采用后序遍历,增加判断只有一边为空的条件。题目要求:求出一棵二叉树的最小深度。迭代法:(层序遍历)

2024-03-14 09:19:32 364

原创 代码随想录day19(2)二叉树:二叉树的最大深度(leetcode104)

思路:首先要区分二叉树的高度与深度。二叉树的高度是任一结点到叶子结点的距离,而二叉树的深度指的是任一节点到根节点的距离(从1开始)。所以求高度使用后序遍历(从下往上,根结点处理在最后,知道孩子高度再加1),而求深度使用前序遍历。而根节点的高度也就是二叉树的最大深度!使用层序也可以,遍历层数即为二叉树最大深度。迭代法层序:(记录遍历层数即可)题目要求:求出二叉树的最大深度。先序:(突出深度回溯)

2024-03-13 16:16:30 1351

原创 代码随想录day19(1)二叉树:对称二叉树(leetcode101)

思路:如果二叉树是对称二叉树,说明此二叉树是可以左右翻转的,所以判断的时候我们同时遍历两棵子树,比较两棵子树的内、外侧是否相等,比较的时候我们实际上比较的是左孩子的左子树与右孩子的右子树以及左孩子的右子树与右孩子的左子树,我们可以采用递归的算法。对于遍历顺序而言,我们应该采用的是后序遍历。对于迭代法,我们可以使用栈或者队列,但是比较的逻辑是和递归一样的。题目要求:判断一棵二叉树是否轴对称。

2024-03-13 15:07:46 412

原创 代码随想录day18(2)二叉树:翻转二叉树(leetcode226)

思路:若想要翻转二叉树,只需要用swap函数将左右孩子节点翻转即可。注意前序和后序遍历均可,但是对于中序来说会将某些结点的左右孩子翻转了两次(画图很明显),硬要用中序只能两次翻转同侧,不建议。层序也同样可以实现二叉树的翻转。题目要求:将一棵二叉树翻转。

2024-03-12 12:31:50 415

原创 代码随想录day18(1)二叉树:二叉树的层序遍历(leetcode102)

思路:实现层序遍历使用队列即可。每个结点遍历结束后,将其左右孩子结点也放入队列。本道题返回的是一个二维数组,即需要将每一层分开,所以还需要size变量记录每层元素个数。注意,内层循环时不能用que.size(),弹出一个结点将孩子结点入队的时候que.size()也会发生变化,使得不知道本层到底有多少个结点。题目要求:实现二叉树的层序遍历。

2024-03-12 12:12:06 392

原创 代码随想录day17(3)二叉树:二叉树的中序遍历(leetcode94)

对于非递归算法则不同,中序遍历时访问顺序与要处理的顺序不同,此时就应借用指针的遍历来帮助访问结点,用栈来处理结点上的元素。对于递归算法的处理与前序、后序基本相同,只是本次应先访问其左节点,然后进行push操作,再访问右节点。思路:对于二叉树的中序遍历,通常可以使用递归算法与非递归(迭代)算法两种。题目要求:实现二叉树的中序遍历。

2024-03-11 13:57:04 498

原创 代码随想录day17(2)二叉树:二叉树的后序遍历(leetcode145)

对于递归算法,我们首先应该确定递归函数的参数以及返回值,其次应该确定终止条件,最后再确定单层递归的逻辑。二叉树的参数一般包括根节点以及结果数组,终止条件应为此时结点为空结点,应该返回到上一层。单层逻辑应该为递归访问其左右孩子结点,然后再将元素push到结果数组中。对于非递归算法,我们应该使用栈来代替递归的过程。对于后序遍历,我们期望得到的序列是左右中,我们可以先将先序遍历的中左右调整为中右左,最后反转result数组为左右中即可。思路:对于二叉树的后序遍历,通常可以使用递归算法与非递归(迭代)算法两种。

2024-03-11 13:15:24 383

原创 代码随想录day17(1)二叉树:二叉树的前序遍历(leetcode144)

对于递归算法,我们首先应该确定递归函数的参数以及返回值,其次应该确定终止条件,最后再确定单层递归的逻辑。二叉树的参数一般包括根节点以及结果数组,终止条件应为此时结点为空结点,应该返回到上一层。单层逻辑应该为先访问此节点,然后递归访问其左、右孩子结点。对于非递归算法,我们应该使用栈来代替递归的过程。对于前序遍历,我们每次先处理中间结点,应该先将根节点放入栈中,为了接下来先处理左孩子,所以应该先将右孩子加入栈,再加入左孩子。思路:对于二叉树的前序遍历,通常可以使用递归算法与非递归(迭代)算法两种。

2024-03-11 13:04:06 353

原创 代码随想录day16 栈与队列:前 K 个高频元素(leetcode347)

思路:我们需要使用map来统计整个数组中元素出现的频率,然后再根据统计好的频率去排序,取得频率前K高的元素。我们不必使用快排实际上我们使用优先级队列即可,我们从队头处取得元素,从队尾处添加元素,我们可以用堆来实现这个队列。我们应该使用小根堆,因为统计最大前k个元素,对于小根堆来说每次都会把最小的元素弹出,最后堆中的元素是前k个最大元素。堆是一棵完全二叉树,树中每个结点的值都不小于或不大于其左右孩子的值,可以分为小根堆或大根堆。题目要求:给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

2024-03-08 21:22:56 373

原创 代码随想录day15(2)栈与队列:滑动窗口最大值(leetcode239)

题目要求:给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。实际上队列不需要维护窗口里所有的元素,我们只需要维护有可能成为窗口里最大的元素,且使得队列里元素是有序的(由大到小),所以我们实现一个单调队列即可。对于此单调队列的push操作,如果push的值大于队列入口元素,则将入口元素弹出,直到push的元素小于等于队列入口元素。对于此单调队列的pop操作,如果窗口弹出的元素值等于单调队列出口的值,弹出此元素,否则不进行操作。

2024-03-07 21:00:21 365

原创 代码随想录day15(1)栈与队列:逆波兰表达式求值(leetcode150)

思路:比较简单,遇到数字时将数字压入栈中,遇到运算符时依次将两个数字弹出进行运算,然后再将结果压入栈中。注意:1.注意减法和除法数字弹出时的顺序,先弹出放在运算符后面,后弹出放在运算符前面,即num2 - num1;2.运算时要把字符串中字符类型的数字转为整数类型。逆波兰表达式是一种后缀表达式,即运算符写在后面,它的优点包括去掉括号后表达式无歧义,且适合用栈操作运算。题目要求:根据给出的逆波兰表达式来求出此表达式的值。逆波兰表达式相当于二叉树的后序遍历。是 C++ 标准库中的一个函数,位于。

2024-03-07 11:46:38 366

原创 代码随想录day14(2)栈与队列:删除字符串中的所有相邻重复项(leetcode1047)

题目要求:给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。在 S 上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操作后返回最终的字符串。思路:还是一道栈的问题。当栈空的时候或者栈顶元素和要入栈元素不同时,将此元素入栈,否则弹出栈顶元素即可。完成一遍遍历后将栈的元素弹出,再将此字符串反转即为所求。我们也可以将字符串直接作为栈,模拟栈的操作即可。

2024-03-06 12:19:17 331

原创 代码随想录day14(1)栈与队列:有效的括号(leetcode20)

思路:比较经典的用栈解决的问题,首先若字符串为奇数时返回false。当遇到左括号时入栈,当遇到右括号时如果与栈顶元素的左括号相匹配,则将栈顶出栈,否则换回false。如果遍历完了字符串后,栈仍不为空,也返回false。技巧:匹配左括号时,我们可以入栈右括号,当字符串中出现右括号时我们只需要比较栈顶元素,二者是否相等即可,更加容易。题目要求:给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

2024-03-06 11:46:12 366

原创 代码随想录day13(2)栈与队列:用队列实现栈(leetcode225)

但实际上我们使用一个队列就可以模拟栈操作,只需要将队列中元素出队后再继续入队,如对列此时有n个元素,我们出队再入队n-1个元素,那么接下来出队的元素就相当于栈弹出的元素。思路:首先的思路就是使用两个队列,入栈的操作不变,如果想弹出一个元素,先将队列1元素出队,只保留一个元素,此元素就是模拟栈弹出的元素。题目要求:使用队列实现栈的push、pop、top(取栈顶元素)、empty操作。

2024-03-05 12:02:20 435

原创 代码随想录day13(1)栈与队列:用栈实现队列(leetcode232)

思路:本题思路比较容易,即用两个栈模拟即可,pop时只需要先判断stackout栈是否为空,如果不空直接弹出,如果空就将stackin栈中所有元素弹人stackout栈再弹出即可。注意peek的实现,不需要重复判断一遍,只需要复用pop,再把弹出的元素放入即可。题目要求:使用栈实现push、pop、empty、peek(返回队列首部元素)。

2024-03-05 11:38:17 441

原创 代码随想录day12(2)字符串:重复的子字符串(leetcode459)

如果一个字符串s内部由重复的子串组成,那么两个s组成的新字符串中如果中间还能出现一个s,则说明时重复子串组成。一、首先对于暴力解法,可以枚举所有的字串进行判断。但是枚举时实际上只需要一次for循环遍历终止位置(每次一定从头开始),而不需要一个for循环获取起始位置,一个for循环获取终止位置,而且不用遍历到结束,字串结束位置大于中间位置一定不能组成重复字符串。题目要求:给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。在由重复子串组成的字符串中,最长相等前后缀不包含的子串就是最小重复子串!

2024-03-04 21:06:29 443

原创 代码随想录day12(1)字符串:找出字符串中第一个匹配项的下标(leetcode28)

KMP算法的关键就是求出next数组,next数组就是一个前缀表,它记录了模式串与主串不匹配时模式串应该从哪里开始重新匹配。如果不存在,则返回 -1。j指向模式串起始位置,i指向文本串起始位置,若不相同就从next数组中寻找下一个匹配位置,如果j指向了模式串的末尾,说明模式串完全匹配文本串里的某个字串。一、初始化:先定义指针i为后缀末尾位置,指针j为前缀末尾位置,然后还要对next数组进行初始化赋值。如果前后缀末尾不同,即s[i]与s[j]不相同,就要找j+1前一个元素在next数组里的值。

2024-03-04 20:29:25 899

原创 代码随想录day11(1)字符串:反转字符串中的单词 (leetcode151)

但如果想让空间复杂度为O(1)的话,可以使用快慢指针,慢指针指向的是最后实际存放的位置,快指针进行判断实现不同处理。所以过程就应该为先去除多余空格,然后整体反转再每个单词反转即可,例如:hello world -> dlrow olleh ->world hello,但是实际实现是有些难度。思路:因为本题没有限制空间复杂度,所以首先想到的是用split直接分割单词,然后将单词倒叙相加。题目要求:给定一个字符串,将其中单词顺序反转,且每个单词之间有且仅有一个空格。此处用来将每个单词反转成正确顺序。

2024-03-02 15:12:30 502

原创 代码随想录day10(2)字符串:反转字符串Ⅱ (leetcode541)

题目要求:给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。如果剩余字符少于 k 个,则将剩余字符全部反转。如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。思路:本题自变量若每次+1然后每到k进行不同操作会比较麻烦,不妨每次i+=2k,在次区间内在进行操作就可以,最后在判断下最后元素剩余个数,进行不同的操作即可。

2024-03-01 22:05:54 453

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除