- 博客(25)
- 收藏
- 关注
原创 代码随想录Day29 | 134.加油站、135.分发糖果、860.柠檬水找零、406.根据身高重建队列
答: 因为当start = i+1, 且这个start没有被后序的更新替代,则说明从start到数组结束位置(gas.size()-1)之间的sum为正数,若记该sum为B,start之前的sum为A,那么A+B=totalSum, 已知totalSum>=0, A<0, B>0, 所以B>-A, 走完一圈的B+A>=0。假设在[0,i]存在一个下标j,使得[j,i]的累加和大于0,由于[0,i]的累加和小于0,则[0,j]的累加和一定小于0,那么其实就会从j重新开始作为起始位置了。
2025-03-11 22:54:05
320
原创 代码随想录Day28 | 122.买卖股票的最佳时机II、55.跳跃游戏、45.跳跃游戏II、1005.K次取反后最大化的数组和
i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。如果 cover 大于等于了终点下标,直接 return true 就可以了。
2025-03-09 21:01:32
158
原创 代码随想录Day26 | 贪心算法理论基础、455.分发饼干、376.摆动序列、53.最大子序和
从代码角度上来讲:遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。针对序列[2,5],可以假设在前面加一个平坡,为[2,5,5],这样prediff为0,curdiff为3,符合上述的规则,这样开头元素就被记录下来了。注意版本一的代码中,可以看出来,是先遍历的胃口,在遍历的饼干,那么可不可以 先遍历 饼干,在遍历胃口呢?用res记录最大和。
2025-03-09 19:47:18
956
原创 代码随想录Day25 | 491.递增子序列、46.全排列、47.全排列II、51.N皇后
思路:下一层可以取的元素应该包含除了本层所取得元素之外的所有元素,因此每次取完元素放到path后,把对应的元素在数组里删除掉,保证下一层没有该元素但有其他未取元素,回溯时再加回来。在全排列中,used数组记录树枝上使用过的元素,因此,只要used[i]==true,就说明nums[i]在这个树枝上已经使用过了,全排列每个元素只能使用一次,因此要跳过。用used数组记录使用过的元素,在回溯中如果发现used[i]==true,则说明树枝上使用过,跳过本次循环。
2025-03-04 18:06:45
318
原创 代码随想录Day24 | 93.复原IP地址、78.子集、90.子集II
参照131.分割回文串的思路去写,终止条件是字符串中"."的数量为3(代表4个数字),然后去判断最后一个数字是否为有效。,若right大于left,则区间不合法,返回false;若left与right不相等且。一遍过, 40.组合总和II 和 78.子集 ,本题就是这两道题目的结合。,说明这个数字以0开头,返回false;否则就取区间子串,转成。判断是否在0到255之间。
2025-03-03 21:54:28
153
原创 代码随想录Day23 | 39.组合总和、40.组合总和II、131.分割回文串
剪枝通常要在for循环里面做文章,上面的代码,对于sum大于target的情况,其实也是进入了下一层递归,只是下一层递归会判断sum>target而直接返回。去重的逻辑(自己想的):通过画树辅助分析,在回溯的时候,弹出去的元素,与下一层循环要加进来的元素不能相等,这样答案就不会重复(当然最一开始先对数组进行排序)用一个bool数组来定义每个下标的元素是否使用过,我们要去重的维度是树层,而树枝上可以有重复元素(实质上是不同下标但数值相同的元素)个人觉得自己的思路更好理解。
2025-03-02 20:55:34
300
原创 代码随想录Day22 | 回溯算法理论基础、77.组合、216.组合总和III、17.电话号码的字母组合
脑补一下执行过程:理解一下一次递归就是一层for循环,上图中每个节点其实都是一次for循环,首先取1,然后递归调用并从2开始搜索,放入2再次递归,得到结果返回;返回后回溯,弹出2,此时又变成1,同时第二层进入下一层for循环,i++为3,此时就把3放入路径再次递归,又得到一个组合…来举一个例子,n = 4,k = 4的话,那么第一层for循环的时候,从元素2开始的遍历都没有意义了。在第二层for循环,从元素3开始的遍历都没有意义了。回溯与递归相辅相成,只要有递归就会有回溯,回溯的逻辑通常在递归函数的下面。
2025-03-01 22:53:35
292
原创 代码随想录Day21 | 669.修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
如果当前节点值小于low,则该节点的左子树一定小于low,但是该节点的右子树中可能还有符合要求的节点,因此要递归调用来修剪右子树,并返回修剪后的根节点;上一层会接住该层返回的根节点,使之成为上一层的左子树或右子树。这道题不到三分钟就AC了,思路很简单,就是反向的后序遍历,从后往前遍历二叉搜索树,那么就相当于一个从大到小的数组,不断累加并修改当前节点的值就可以了。整体思路:选取一个中间节点,分为左区间和右区间,左区间继续构造左子树,右区间继续构造右子树。本题在选取时,一定要选取。的节点,才能保证是平衡的。
2025-02-22 19:28:27
381
原创 代码随想录Day19 | 235.二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点
之间的节点一定就是最近公共祖先。因为这样说明p在该节点的左子树,q在该节点的右子树,那么无论再往左遍历还是往右遍历,一定会错过p和q中的一个,只有当前节点才能连接p和q。如果当前层是要删除的节点,分五种情况去处理,最后会返回删除后的一棵子树,中心思想:在二叉搜索树中插入任何一个节点,都可以在叶子节点找到位置。重点理解:从上往下遍历,遇到的第一个节点值在。,成为上一层的左子树或者右子树。
2025-02-22 17:05:25
308
原创 代码随想录Day18 | 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
扫描中序遍历序列,用base记录当前的数字,用count记录当前数字重复的次数,用maxCount来维护已经扫描过的数当中出现最多的那个数字的出现次数,用res数组记录出现的众数。我们平时遍历都是从上往下,并不能从下往上,但是递归分为“递”和“归”两个过程,递的过程是从上往下,归的过程就是从下往上处理了,因此要用后序遍历(左右中)所以其实可以抽象成,在一个升序数组里找到最小差,需要两个指针指向相邻元素,遍历数组不断更新最小差值,最后得到的最小值就是想要的结果。看到二叉搜索树,一定要想到。
2025-02-22 15:28:14
253
原创 代码随想录Day17 | 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
用递归法来做,前序遍历,如果root1为空就返回root2,如果root2为空就返回root1,都不为空则相加,接着该结点的左孩子是root1的左孩子与root2的左孩子合并,该结点的右孩子是root1的右孩子与root2的右孩子合并。中序遍历是指,先判断左子树是否为二叉搜索树,再处理根节点的值判断逻辑,最后判断右子树是否为二叉搜索树(把遍历顺序想成左子树、根节点、右子树的顺序,抽象起来理解)这个主要与终止条件有关,终止条件是数组元素个数为1,要求传入的数组中的个数必须大于等于1。
2025-02-18 20:50:52
406
原创 代码随想录Day16 | 513.找树左下角的值、112. 路径总和、 106.从中序与后序遍历序列构造二叉树
递归法:因为本题没有中间结点的处理逻辑,使用前序、中序、后序遍历均可(保证先处理左,再处理右即可)。参数有要遍历的树的根节点,还有一个int型变量来记录最长深度,返回值类型为void。当遇到叶子节点时,比较当前深度与最大深度,更新最大深度和左下角的值。递归过程要回溯,先递归左子树,再递归右子树迭代法:迭代法更加简单,使用层序遍历,需要先将右孩子放入,再将左孩子放入,这样保证每一层都是从右往左遍历,最后一个元素即是最后一层最左边的元素。112. 路径总和递归思路:如果是一棵空树,直接返回false;如果
2025-02-18 15:51:34
412
原创 代码随想录Day15 | 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和、222.完全二叉树的节点个数
【代码】代码随想录Day15 | 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和、222.完全二叉树的节点个数。
2025-02-11 18:08:52
185
原创 代码随想录Day14 | 226.翻转二叉树、101. 对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度
参数就是要传入节点的指针,不需要其他参数了,通常此时定下来主要参数,如果在写递归的逻辑中发现还需要其他参数的时候,随时补充。返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为。因为是前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。相比较上题,要多考虑两种情况,即只有右边有子树、只有左边有子树。用递归法来做,考虑递归出口,如果遍历到的当前两个指针有。用哪种遍历顺序:前序和后序比较方便,中序代码比较绕。
2025-02-11 15:48:56
254
原创 代码随想录Day12 | 二叉树理论基础、递归遍历、迭代遍历、统一迭代、层序遍历
那么再看看中序遍历,中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了。因为前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以刚刚才能写出相对简洁的代码,满二叉树:只有度为0和度为2的结点,并且度为0的结点在同一层上。前序遍历的顺序是中左右,先将根结点放入栈,然后将右孩子放入栈,再加入左孩子。看如下中间节点的顺序,就可以发现,中间节点的顺序就是所谓的遍历方式。
2025-02-10 16:50:46
815
原创 代码随想录Day11 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
想象自己在飞机上看下面的山,数字代表山的高度,首先进入视野的是{2,1,4},但由于2和1比4小,离开视野又比4早,所以2和1永远不可能是视野内的最高山;利用栈来存储进行运算的数字,遇到操作符就弹出两个数,第一个数放在操作符右边,第二个数放在操作符左边,然后将运算结果重新压入栈中,最后栈中的元素就是运算结果。这道题目要用小顶堆,因为堆只能弹出堆顶的元素,用小顶堆(k个元素),每次都弹出堆顶的最小元素,最后堆中剩下的就是最大的k个元素。而且优先级队列内部元素是自动依照元素的权值排列。统计每个元素出现的频率,
2025-02-08 20:10:49
455
原创 代码随想录Day10 | 232.用栈实现队列、225. 用队列实现栈、20. 有效的括号、1047. 删除字符串中的所有相邻重复项
弹出元素时,把qu1最后一个之前的元素全部移到qu2中,然后qu1弹出最后一个元素(即栈中的顶部元素),最后qu2中的元素重新赋值给qu1,qu2清空,实现pop。这道题目自己写的AC了,思路就是利用一个栈,遇到左括号就入栈,遇到右括号就把它与栈顶元素进行比较,如果匹配就接着下一轮循环,如果不匹配就说明无效,返回。例如:输入栈元素{5,6,7},输出栈元素{1,2,3,4},则模拟的队列中的元素顺序为{1,2,3,4,5,6,7}。,此时弹出最后一个元素后,队列内的顺序就是栈中元素的顺序。
2025-02-07 16:37:25
225
原创 代码随想录Day9 | 151.翻转字符串里的单词、卡码网:55.右旋转字符串、28. 实现 strStr()、459.重复的子字符串
是前一次循环的最长相等前后缀,每次循环时,j都在理论上最大长度处,也就是最好的情况,接着进行匹配,如果匹配就加1,不匹配那就要回退了,回退到冲突前一个子串的最长相等前后缀,一直到匹配为止)上述在匹配过程中,第一次匹配,遇到f时匹配不成功,这时要找到f前面子串的最长相等前后缀,从最长前缀的后一个字母开始匹配,下标就是字符串。整体思路:先把整个字符串反转,这样每个单词的位置与我们想要的相同,但单词内部还是倒序的,接着再把每个单词分别反转即可。是否匹配,如果不匹配,需要找冲突字母之前的最长相等前后缀,即。
2025-02-05 20:48:48
704
原创 代码随想录Day8 | 344.反转字符串、541. 反转字符串II、卡码网:54.替换数字
思路:发现题目要求是以2k个为单位处理字符串的,当发现题目要求我们成段处理字符串时,要想到for循环里i也可以成段跳,即每次加2k。双指针法:头尾各有一个指针,指向要交换的位置,同时向中间移动收缩。,如果当前不是数字,直接赋值给。如果是数字,依次赋值。
2025-02-05 15:02:22
228
原创 代码随想录Day7 | 454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和
解题思路:本题把4个数组分成两两一组,分别遍历,将a+b的值和出现次数存放在map中,再进行遍历另外两个数组,如果0-(a+b)在map中出现过,count加key对应的value(即次数)。因为本题不仅要存储a+b是否出现过,也要存储a+b出现的次数,有几个a+b就说明在A和B数组中有几个不同位置的元素相加和为a+b。如果与后一个元素比较,因为。代表b),但三元组是允许重复的,如{-1,-1,2},这样判断就会漏掉这种情况。,如果当前三个元素相加大于0,则应该让总和减小,因为已经是排序过的,所以只能让。
2025-02-04 17:47:46
811
原创 代码随想录Day6 | 哈希表理论基础、242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和
std::map也是一样的道理。std::unordered_set底层实现为哈希表,std::set 和std::multiset 的底层实现是红黑树,红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。**再遍历 字符串s的时候,当我们要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的,如果需要集合是有序的,那么就用set,如果要求不仅有序还要有重复数据的话,那么就用multiset。
2025-02-02 19:39:47
794
原创 代码随想录Day4 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II
用快慢指针,快指针每次移动两个结点,慢指针每次移动一个结点,如果快慢指针相遇,则证明有环。: 是指同一个结点,即同一个地址存储的同一个结点,并不是指结点的数值相等。因为快指针的速度是慢指针速度的2倍,假设慢指针在第一圈的时候没被追上,则慢指针走到第一圈终点时,快指针已经走了两圈,所以一定可以追上。两个链表的长度不一定相等,但相交部分一定是后部分,即如果从某个结点开始相交,则后面的部分一定都相交。指向2结点,1结点无法访问到;也就是说,如果两个链表的当前结点,后面的节点数量都不一样,那当前结点一定不是交点。
2025-01-25 20:20:59
1014
原创 代码随想录Day2 | 209.长度最小的子数组、59.螺旋矩阵II、区间和、开发商购买土地
重点在于如何移动起始位置,以及移动起始位置时为什么要用。
2025-01-23 21:55:05
740
原创 代码随想录Day1 | 数组理论基础、704. 二分查找、27. 移除元素
对于二维数组如何存放,不同语言不一样。比如C++就是连续存放的,而Java则不是。
2025-01-22 17:37:32
679
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人