自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录算法训练营第三十四天 | 62.不同路径 63.不同路径II 343.整数拆分

代码里for循环的终止条件,一旦遇到obstacleGrid[i][0] == 1的情况就停止dp[i][0]的赋值1的操作,dp[0][j]同理。首先dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理。因为从(0, 0)的位置到(i, 0)的路径只有一条,所以dp[i][0]一定为1,dp[0][j]也同理。dp[i][j] :表示从(0 ,0)出发,到(i, j)有dp[i][j]条不同的路径。1.确定dp数组以及下标的含义。

2025-04-01 21:58:50 251

原创 代码随想录算法训练营第三十二天 | 509.斐波那契数 70.爬楼梯 746.使用最小花费爬楼梯

dp[i - 1],上i-1层楼梯,有dp[i - 1]种方法,还有就是dp[i - 2],上i-2层楼梯,有dp[i - 2]种方法,dp[i]是两种方法之和,所以dp[i] = dp[i - 1] + dp[i - 2]dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] + cost[i - 1],dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。dp[i]是依赖 dp[i - 1] 和 dp[i - 2],遍历的顺序一定是从前到后遍历的。

2025-03-30 18:00:38 1012

原创 代码随想录算法训练营第三十一天 | 56.合并区间 738.单调递增的数字 968.监控二叉树

按照左边界从小到大排序之后,如果 intervals[i][0] <= intervals[i - 1][1] 即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。思路:输入:intervals = [[1,4],[4,5]] 输出:[[1,5]] 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。每个节点可能有几种状态:0:该节点无覆盖 1:本节点有摄像头 2:本节点有覆盖。左孩子有覆盖,右孩子有覆盖,此时中间节点应该就是无覆盖的状态了。

2025-03-29 17:51:18 495

原创 代码随想录算法训练营第三十天 | 452.用最少数量的箭引爆气球 435.无重叠区间 763.划分字母区间

2.如果当前区间的左边界<上一个区间的右边界,说明区间有重叠,将当前区间的右边界改为两个重叠区间右边界最小的;因为遍历进入下个区间,前两个区间有重叠,下个区间左边界与前两个区间重叠右边界最小的比较(因为前两个重叠区间移除一个),有重叠说明下个区间也是重叠。思路:输入: intervals = [[1,2],[2,3],[3,4],[1,3]] 输出: 1 解释: 移除 [1,3] 后,剩下的区间没有重叠。1.如果当前气球区间左边界>上个气球区间右边界,两气球区间没有重叠,需要两个箭引爆气球;

2025-03-28 15:41:36 531

原创 代码随想录算法训练营第二十九天 | 134.加油站 135.分发糖果 860.柠檬水找零 406.根据身高重建队列

局部最优可以推出全局最优。思路:输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]] 输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]如果ratings[i] > ratings[i - 1] 那么[i]的糖一定要比[i - 1]的糖多一个,所以贪心:candyVec[i] = candyVec[i - 1] + 1。局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。

2025-03-27 19:44:00 842

原创 代码随想录算法训练营第二十八天 | 122.买卖股票的最佳时机II 55.跳跃游戏 45.跳跃游戏II 1005.K次取反后最大化的数组和

假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0],相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。贪心的思路,局部最优:当前可移动距离尽可能多走,如果还没到终点,步数再加一。局部最优:只找数值最小的正整数进行反转,当前数值和可以达到最大(例如正整数数组{5, 3, 1},反转1 得到-1 比 反转5得到的-5 大多了),全局最优:整个数组和达到最大。

2025-03-26 14:43:40 585

原创 代码随想录算法训练营第二十七天 | 455.分发饼干 376.摆动序列 53.最大子序列和

在计算是否有峰值的时候,大家知道遍历的下标 i ,计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i]),如果prediff < 0 && curdiff > 0 或者 prediff > 0 && curdiff < 0 此时就有波动就需要统计。输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6,连续子数组[4,-1,2,1] 的和最大,为 6。视频讲解:​​​​​​​。视频讲解:​​​​​​​。

2025-03-25 09:39:53 658

原创 代码随想录算法训练营第二十五天 | 491.递增子序列 46.全排列 47.全排列II

输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]输入:nums = [1,1,2] 输出:[[1,1,2], [1,2,1], [2,1,1]]used数组,记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次。

2025-03-23 19:14:43 349

原创 代码随想录算法训练营第二十四天 | 93.复原IP地址 78.子集 90.子集II

输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]递归调用时,下一层递归的startIndex要从i+2开始(因为需要在字符串中加入了分隔符.),同时记录分割符的数量pointNum 要 +1。时间复杂度: O(3^4),IP地址最多包含4个数字,每个数字最多有3种可能的分割方式,则搜索树的最大深度为4,每个节点最多有3个子节点。求取子集问题,不需要任何剪枝,子集就是要遍历整棵树。

2025-03-22 17:13:54 363

原创 代码随想录算法训练营第二十三天 | 39.组合总和 40.组合总和II 131.分隔回文串

如果candidates[i] == candidates[i - 1] 并且 used[i - 1] == false,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1],for循环里就应该做continue的操作。思路:输入: candidates = [2,5,2,1,2], target = 5, 输出:[[1,2,2],[5]]切割过的位置,不能重复切割,所以,backtracking(s, i + 1);

2025-03-21 21:56:39 686

原创 代码随想录算法训练营第二十二天 | 77.组合 216.组合总和III 17.电话号码的字母组合

叶子节点就是要收集的结果集,终止条件就是index 等于输入的数字个数(digits.size)了(本来index就是用来遍历digits的),然后收集结果,结束本层递归。第一次取1,集合变为2,3,4 ,因为k为2,我们只需要再取一个数就可以了,分别取2,3,4,得到集合[1,2] [1,3] [1,4],以此类推。还有一个参数就是int型的index记录遍历第几个数字了,用来遍历digits的,同时index也表示树的深度。这棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不再重复取。

2025-03-20 19:37:48 875

原创 代码随想录算法训练营第二十一天 | 669.修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树

将下一层处理完左子树的结果赋给root->left,处理完右子树的结果赋给root->right,最后返回root节点。如果root(当前节点)的元素小于low,那么应该递归右子树,并返回右子树符合条件的头结点;接着划分区间,root的左孩子接住下一层左区间的构造节点,右孩子接住下一层右区间构造的节点。要定义一个全局变量pre,用来保存cur节点的前一个节点的数值,定义为int型就可以了。定义的是左闭右闭的区间,所以当区间 left > right的时候,就是空节点了。视频讲解:​​​​​​​。

2025-03-18 17:32:22 363

原创 代码随想录算法训练营第二十天 | 235.二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

cur节点在区间(p->val <= cur->val && cur->val <= q->val)或者 (q->val <= cur->val && cur->val <= p->val)中,那么cur就是最近公共祖先了,直接返回cur。第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点。450.删除二叉搜索树中的节点。

2025-03-17 19:38:43 348

原创 代码随想录算法训练营第十八天 | 530.二叉树搜索树的最小绝对差 501.二叉搜索树中的众数 98.二叉树的最近公共祖先

判断一个节点是节点q和节点p的公共祖先:如果递归遍历遇到q,就将q返回,遇到p 就将p返回,那么如果左右子树的返回值都不为空,说明此时的中节点,一定是q 和p 的最近祖先。2.在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。我们要返回最近公共节点,返回值是TreeNode * ,如果遇到p或者q,就把q或者p返回,返回值不为空,就说明找到了q或者p。遇到空的话,因为树都是空了,所以返回空;

2025-03-16 16:43:08 541

原创 代码随想录算法训练营第十七天 | 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL),反过来如果t2 == NULL,那么两个数合并就是t1。法三:设置一个节点pre保存中序遍历前一个节点,二叉搜索树按中序遍历:左<中<右,当前节点值<=前一个节点值,不是二叉搜索树;参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。递归函数的参数传入的是根节点和要搜索的数值,返回的就是搜索数值所在的节点。

2025-03-15 10:24:47 417

原创 代码随想录算法训练营第十六天 | 513.找树左下角的值 112.路径总和 106.从中序与后序遍历序列构造二叉树

1.后序数组为0,空节点 2.后序数组最后一个元素为节点元素 3.寻找中序数组位置作切割点 4.切割中序数组,切成中序左数组和中序右数组 5.切割后序数组,切成后序左数组和后序右数组 6.递归处理左区间和右区间区间。判断是否最左边:使用前序遍历,优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。根据后序遍历,说明最后一个节点就是根节点,根据中序遍历和已经的根节点,可以把二叉树分为左右两部分。迭代法:层序遍历,求最后一层的第一个节点的值。左下角值:二叉树里最后一行最靠左侧的值。

2025-03-13 20:10:26 476

原创 代码随想录算法训练营第十五天 | 222.完全二叉树的节点个数 110.平衡二叉树 257.二叉树 的所有路径 404.左叶子之和

如果该节点的左节点不为空,该节点的左节点的左右孩子为空,则找到了一个左叶子)如果不是满二叉树,递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量(满二叉树的结点数=2的深度次方-1)求出其左右子树的高度,当发现一个节点下左右子树的高度差超过1,不是平衡二叉树,返回-1,如果差值小于等于1,则返回当前二叉树的高度。当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和右子树左叶子之和,相加便是整个树的左叶子之和。257.二叉树的所有路径。视频讲解:​​​​​​​。

2025-03-13 09:14:25 340

原创 代码随想录算法训练营第十四天 | 226.翻转二叉树 101.对称二叉树 104.二叉树的最大深度 111.二叉树的最小深度

只能用后序遍历(左右中),不断收集左右孩子的信息返回给上一个节点,才知道左节点为根节点数和右节点为根节点的数是否可以相互翻转,只有后序遍历底部孩子信息比较是否相等的信息返回给上一层,比较的是两个子树的里侧和外侧的元素是否相等。注:不能中序遍历(左根右:左孩子处理后,根翻转,最后处理右孩子又变成了翻转原来的左孩子,某些节点左右孩子翻转了两次,最后处理应改成翻转左孩子节点)要判断是不是对称树,比较的是根节点的两个子树是否是相互翻转的,参数是左子树节点和右子树节点,返回值是bool类型。

2025-03-12 10:23:57 466

原创 代码随想录算法训练营第十三天 | 递归遍历 迭代遍历 层序遍历

【后序遍历】:左右中,和前序遍历一样,先把根节点放入栈中,然后依次加入左孩子和右孩子,得到的顺序是中右左,最后在反转result数组,输出的结果顺序就是左右中了。思路:层序遍历是一层一层的来遍历二叉树,设置一个变量depth记录层数,每遍历一层depth+1,遍历的层数就是二叉树的深度。【前序遍历】:中左右,每次先处理的是根节点,先把根节点放入栈中,栈是先进后出,所以先加入右孩子,再加入左孩子。思路:也可用层序遍历,只有当结点的左右孩子为空时,遍历到最低点,此层的depth就为最小高度。

2025-03-11 16:16:39 788

原创 代码随想录算法训练营第十一天 | 150.逆波兰表达式求值 239.滑动窗口最大值 347.前K个高频元素

遇到运算符,依次弹出栈顶的两个数字做相应的加减乘除,将运算后的结果写入栈顶。push:如果push进来的元素比前面的都大,那前面的元素都要出队排除,直到前面元素没有新加入的元素大为止。思路:小顶堆,根结点的值<左右结点的值,将k以外的元素都移出去,剩下的就是k个高频元素。统计最大前k个元素,小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。只需要维护有可能成为最大值的放在队列出口处,同时保证队列里的元素数值是由大到小的。pop:如果窗口移除的元素等于单调队列的出口元素,将队列元素弹出放入。

2025-03-09 23:27:51 250

原创 代码随想录算法训练营第十天 | 232.用栈实现队列 225.用队列实现栈 20.有效的括号 1047.删除字符串中的所有相邻重复串

出队:在pop的时候,输出栈如果为空,就把进栈数据全部导入进来,再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。遍历元素先和栈里面的元素比较,如果栈本来就是空的,直接把遍历的元素放进来(栈是存放遍历过的元素,帮忙做消除);用栈来存放存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素(遍历到a了,要去栈里看一下前一个字母是不是a)。队列先进先出,如123队列输出123。用栈实现队列,队列先进先出,栈先进后出,如123,队列输出123,栈输出321。

2025-03-08 11:28:39 995

原创 代码随想录算法训练营第九天 | 151.反转字符串里的单词 卡码55.右旋字符串 28.实现strStr() 459.重复的子字符串

前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配,在某个字符失配时,前缀表会告诉下一步匹配中,模式串应该跳到哪个位置。next数组是前缀表,前缀表用来回退的,它记录了模式串和主串不匹配的时候,模式串应该从哪里开始重新匹配;j=0已经到了初始位置没必要回退,next[0]=0,再回退j=next[j-1]下标会出现-1越界。前缀末尾和后缀末尾不匹配的时候,j是向前回退,j看前一位的next数组的值就是要回退的下标。next[1]=1,因为aa只有一个相等的真前缀和真后缀:a,长度为 1。

2025-03-06 23:59:05 645

原创 代码随想录算法训练营第八天 | 344.反转字符串 541.反转字符串II 卡码网54.替换数字

思路:每计数至2k个字符,反转前k个字符;剩余[k,2k)个字符,反转前k个字符;(i+k<s.size())j如果指向字母,i同步j所指向的字母;j如果j指向数字,i从尾部放入number的倒序。双指针,一个指针指向字符串起始位置,一个指针指向字符串末尾位置,然后双指针法:i指向新长度的末尾,j指向旧长度的末尾。时间复杂度O(n),空间复杂度O(1);时间复杂度O(n) 空间复杂度O(1)剩余[0,k)个字符,反转剩余所有字符。时间复杂度O(n) 空间复杂度O(1)卡码网:54.替换数字。

2025-03-05 13:01:17 414

原创 代码随想录算法训练营第七天 | 454.四数相加II 383.赎金信 15.三数之和 18.四数之和

四数之和的双指针解法是两层for循环nums[a] + nums[b]为确定值,依然是循环内有left和right下标作为双指针,找出nums[a] + nums[b] + nums[left] + nums[right] == target的情况,后面left、right和三数之和一样。如果hash数组中有为负值的元素,必然有A里面多的字母是B里面没有的,A不能由B里面的字母组成。如果nums[i]+nums[left]+nums[right]>0,要把三个数值和变小,right就往左移right--,

2025-03-04 15:57:25 351

原创 代码随想录算法训练营第六天 | 242.有效的字母异位词 349.两个数组的交集 202.快乐数 1.两数之和

然后判断是否为快乐数,新建一个unordered_set哈希结构存放每次正整数各个位置的平方和,如果sum=1就是快乐数,sum重复出现会陷入无限循环不是快乐数,sum为没有出现过的数新加入result中记录。步骤二:用nums2做查询操作,再用nums2遍历每一个元素去查询哈希表里,看有没有在哈希表中出现过,如果出现过放到result集合里(result集合是去重的)把遍历过的元素加到一个集合里,每次遍历一个新的位置之后,判断想要寻找的元素是否在集合里出现过。题目链接:​​​​​​​。

2025-03-03 17:05:26 950

原创 代码随想录算法训练营第四天 | 24.两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题02.07链表相交 142.环形链表II

思路:cur的next指针域指向链表交换后的第一个结点2,用临时指针tmp1保存结点2的前一个结点1(因为cur->next在步骤一被改变了),临时指针tmp2保存结点2的后一个结点3(因为cur->next->next->next在步骤三被改变了)分析:如果有环,快指针相对于慢指针来说,每次移动一个结点(相对于慢指针,快指针的速度每次是移动一个结点的移动速度靠近慢指针,两个指针一定会相遇)步骤一:cur->next=cur->next->next;x=(n-1)(y+z)+z,若n=1,x=z;

2025-03-01 21:53:08 403

原创 代码随想录算法训练营第三天 | 203.移除链表元素 707.设计链表 206.反转链表

方法一:双指针法,初始化 cur = head,pre = NULL,cur->next 的指向原本指向下个结点, 改变cur->next指向pre ,此时已反转了第一个节点,将cur和pre继续均往后移动依次遍历。被删除结点的前一个结点指针next域指向被删除结点的后一个结点,C++释放被删除结点空间。设置一个虚拟头结点,放在链表头结点的前方,删除结点无论是否头结点可统一处理。视频讲解:​​​​​​​​​​​​​​。题目链接:​​​​​​​。视频讲解:​​​​​​​。203.移除链表元素。

2025-02-28 20:21:47 426

原创 代码随想录算法训练营第二天 | 209.长度最小的子数组 59.螺旋矩阵II

题目链接:209. 长度最小的子数组 - 力扣(LeetCode)文章讲解:代码随想录视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili思路:滑动窗口滑动窗口就是满足窗口内所有数值之和 ≥ target 的长度最小的连续子数组。窗口起始位置i移动:已有窗口数值之和≥target的数组条件下,窗口起始位置i可继续向右移动(缩小窗口),直到找出满足>=target最小窗口长度的起始位置i。窗口结束位置j移动:for循环遍历数组的指针,满足窗口数值之和≥targe

2025-02-27 21:12:20 359

原创 代码随想录算法训练营第一天 | 704.二分查找 27.移除元素 977.有序数组平方

704. 二分查找文章讲解:代码随想录视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili思路:设置left,right下标初始值,while区间循环,mid指向(left+right)/2;目标值target<nums[mid],目标值在mid左半部分,改变right将区间缩小到左半部分;目标值target>nums[mid],目标值在mid右边半部分,改变left将区间缩小到右半部分;目标值target=nums[mi

2025-02-26 00:27:31 582

空空如也

空空如也

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

TA关注的人

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