- 博客(44)
- 收藏
- 关注
原创 【代码随想录|动态规划 回文子串】
就只考虑一个,要么考虑前面一个(dp[i][j-1]),要么考虑后面一个(dp[i][j-1]): dp[i][j]=max(dp[i][j-1],dp[i][j-1]);|||、i跟j相差大于1,那就查看他前一个区间(dp[i + 1][j - 1])的是否是回文串,如果同样是,那就计数。要推出dp[i][j]的值首先要知道dp[i + 1][j - 1]的值,所以遍历顺序得是从下到上 从左到右。dp[i][j]:字符串s在[i,j]范围内最长的回文子序列的长度为dp[i][j]3.dp数组的初始化。
2025-03-05 20:49:36
862
原创 【代码随想录|动态规划 编辑距离问题】
那么dp[i][j]的值和删掉这两个字符的值相等 dp[i][j]=dp[i-1][j-1];dp[i][0]是指word1是空字符,word2要删多少个字符才为空,那 dp[i][0]=i;dp[0][j]是指word2是空字符,word1要删多少个字符才为空,那dp[0][j]=j;word1 word2都删(dp[i-1][j-1]+2)以i-1为结尾的s子序列中出现以j-1为结尾的t的个数是dp[i][j]就延续我s的上一位的情况 dp[i][j]=dp[i-1][j];
2025-02-14 11:17:19
760
原创 【代码随想录|子序列问题】
而递推公式中加上max的话dp[s.size()][t.size()]的值最后是3,最后和s.size()(4)不相等返回false答案也对,但是这里在检查到s里的‘’x‘’的时候,不是t的子串了,所以用0来表示可能更准确一些。如果第i-1个字符和j-1个字符不相等,那就保持前面字符相等的状态 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);dp[i][j]:以[0,i-1]的nums1和以[0,j-1]的nums2的最长公共子序列的长度。因为这里求的子序列是。
2025-02-11 10:31:40
751
原创 【代码随想录|子序列系列300,674,718】
所以要if(nums1[i-1]==nums2[j-1])dp[i][j]=dp[i-1][j-1]+1;不可能有以-1结尾的nums数组,所以是没有意义的,为了在比较第一个字符的时候连续子序列能为1所以初始化为0。dp[i][j]:以i-1结尾nums1数组和j-1结尾的nums2数组的最长子数组的长度。dp[j]主要遍历0到i-1个值,比较i前面的值是否小于i,从前往后遍历和从后往前遍历都行。dp[i]:以nums[i]结尾的最长递增子序列的长度。不加max dp[i]:1,2,1,2。
2025-02-08 12:04:13
472
原创 【代码随想录|股票买卖的最佳时机02】
dp[i][3]:冷冻期 前一天是具体卖出股票状态 dp[i-1][2]dp[i][2]:具体卖出股票状态 前一天是持有股票状态 dp[i][0]+prices[i]dp[i][0]:持有股票状态 保持前一天的状态dp[i-1][0]dp[i][1]:保持卖出股票状态 前一天是冷冻期 dp[i-1][3]dp[i][j]:第i天的状态为j,所剩下的最大现金为dp[i][j]
2025-02-06 11:22:22
819
原创 【代码随想录|买卖股票的最佳时机】
dp[i][1]的值可以沿用前一次的值(dp[i-1][1])和第一次买入股票(dp[i-1][0]-prices[i])dp[i][2]的值可以沿用前一次的值(dp[i-1][2])和第一次卖出股票(dp[i-1][1]+prices[i])dp[i][3]的值可以沿用前一次的值(dp[i-1][3])和第二次买入股票(dp[i-1][2]-prices[i])dp[i][4]的值可以沿用前一次的值(dp[i-1][4])和第二次卖出股票(dp[i-1][3]+prices[i])
2025-01-24 11:19:42
498
原创 【代码随想录|打家劫舍198,213,337】
如果要使用递推公式考虑,要使用前一个和前两个数组的值,从0开始可能会超限,所以直接把dp[0]赋值nums[0],dp[1]赋值nums[0]和nums[1]的最大值。敲代码的时候我是按下面这个来敲的,答案是错的,感觉就是因为这里的dp数组是考虑进了之前的房屋的值的,但是我直接加nums的值的话是不会考虑进去的,只有单拎的值。因为相邻的房屋不能偷,所以我第i个的dp值就是考虑我偷当前的房间加上前两个的房间的值和我只偷前一个房间的值进行比较选最大值。就是 当前节点的值+不偷左孩子的金钱+不偷右孩子的金钱。
2025-01-21 12:28:20
532
原创 【代码随想录|动态规划322.零钱兑换 279.完全平方数 139.单词拆分】
遍历顺序是先遍历背包再遍历物品,因为单词的顺序是固定的,要用排列数,因为用排列数进行遍历的话是把每一个物品进行遍历跟我现在遍历到的字符串相等了之后才赋值为1。不要这个物品是dp[j],要这个物品的话就先把他的位置腾出来,然后我算上这个物品dp[j - coins[i]] + 1,因为求的最小值,就加个min。经典的题是求装满背包能装下的最大价值,这里求的是我要几张钱才能凑到我的总额,那就是装满这个背包需要几件物品。递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
2025-01-17 09:29:13
273
原创 【代码随想录|完全背包问题】
而外层遍历背包内层遍历物品就不一样了,每一层的dp[j]都是在固定j的情况下,把物品从头开始遍历,所以dp[j]来自于上一层的结果,而上一层的结果又遍历了所有物品,所以这种遍历方式会出现【物品1,物品2,物品1】这种情况,dp[j]一定是来自于外层上一次的结果,而外层上一次的结果一定是来源于上一个物品的dp数组,也就是只会出现【物品1,物品1,物品2】这种情况,而物品2不会出现在物品1之前,那我们一共有多少种方法可以到dp[5]呢,就是dp[4]+dp[3]+dp[0](1+2+1)为4 刚好装满。
2024-12-29 21:07:05
802
原创 【代码随想录|动态规划背包问题应用】
1049. 最后一块石头的重量 II - 力扣(LeetCode)因为这里是求石头相撞留下来最小的重量,就可以用背包问题来解,把所有石头尽量分成重量相同的两堆,然后再相减,就是留下来最小的重量了相撞完一堆石头的总重量是dp[target],另一堆就是sum - dp[target]。把他们相减就是要返回的sum-2*dp[target];动规五部曲:1、确定dp数组的含义:dp[j] 表示容量为j的背包,可以装的最大价值为dp[j]这个数3、确定dp数组如何初始化:题目条件是。
2024-12-27 18:03:55
887
原创 【代码随想录|动态规划背包问题】
01背包:n种物品,每种物品只有一个完全背包:n种物品,每种物品有无限个多重背包:n种物品,每种物品的个数各不相同。
2024-12-22 20:15:45
596
原创 【MATLAB课设五子棋教程】(附源码)
设计一个matlab的app是我们期末的答辩内容,我做的这个五子棋主要参考了b站up主唤醒手腕的代码和教程,然后在matlab窗口实现的改到app里实现。最后答辩的实验成绩好像是90+这个app的mlapp文件放在文章最后了,需要自取。
2024-12-21 11:21:31
503
原创 【代码随想录|动态规划02】
2.递推公式:这里有障碍的地方就直接continue,让它等于0后面也方便计算,然后dp[i][j]=dp[i-1][j]+dp[i][j-1];1.确定dp[i]含义 dp[i][j]是位于第i行第j列所能走的不同路径。2.递推公式:dp[i][j]=dp[i-1][j]+dp[i][j-1];每一行初始为1 dp[i][0]=1;每一列初始为1 dp[0][j]=1;每一行初始为1 dp[i][0]=1;每一列初始为1 dp[0][j]=1;5.(打印dp数组)
2024-12-17 20:57:05
259
原创 【代码随想录|贪心算法05】
但是如果直接把前一位-1后一位设置成9,如果传入的数是1000的话,结果就会变成0900,所以我设置一个flag来记录当前数要设置为9的地方,后面统一都设置为9了,因为我只要这个数为9,后面的数肯定都是9(没有比9更大的数了)因为从前往后进行修改的话,我后面的数修改了会把一个数-1,会影响已经遍历的的数的大小关系,从后往前遍历的话,我就可以一边遍历一边用修改后的结果。思路就是把从后往前遍历,前面的数比现在的数大的话就把前面的数-1,让后面这个数有选择大的数(9)的可能。我滴妈,这道题的思路好牛啊。
2024-12-10 20:35:27
573
原创 【代码随想录|贪心算法重叠区间问题】
这道题感觉跟上一道题很相像,因为这道题是要去掉重叠区间,让剩下的区间都不重叠,思路就是我们进行先按左区间从小到大进行遍历,如果遍历到重叠的区间我们就要去掉一个重叠区间,所以定义的count++,为了判断后面还有没有区间跟他俩重合,我直接更新区间的右边界来和后面的进行比较。思路就是我们比较这个气球和上一个气球有没有重合的,重合我们一根箭一起就射了,不重合我们就要单独拿根箭射它,每个气球都有左边界points[i][0],和右边界points[i][1],假设有字符串S = "abacabad"
2024-12-06 21:33:02
1091
原创 【代码随想录|贪心算法03】
这里的思路是保存每个站的的加油量减去消耗量(cursum),他为正我肯定就能进行遍历,然后如果一个不小心,你油不够了(cursum<0),那这个点前面的点肯定都不够这个点消耗的了,因为题目说存在解结果是唯一的,那我只要从后面的第一个油是正数的点开始遍历就足够了(按道理我第二个油是正数的点可能也可以,但是题目说只有一个解所以取第一个)在做的时候,发现我这个不对,我最开始想的是我要第一个正数点那,取到了我退出了不就好了,然后报错的一组数据是。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。
2024-12-02 21:18:17
981
1
原创 【代码随想录|贪心算法02】
思路感觉就是先从下标0开始,遍历到它所能跳的覆盖范围,看它覆盖的元素能不能增加它的覆盖范围,比如上面这个,如果我从0跳4下就能跳到终点,0+4>=5-1(cover>=nums.size()-1)就说明可以到达最后一个下标。我觉得的思路是我遍历到我现在能覆盖的范围(cur),到了覆盖范围cur的边缘了,我才跳一步,而且这一步的距离一定要是保存的最大距离next,然后我不断更新next的值,只要它到达终点就赶紧退出返回result的值。局部最优:把绝对值大的负数变为正数,剩余的K把最小的正数进行取反。
2024-11-27 21:29:44
673
原创 【代码随想录|回溯算法排列问题】
这道题和46.全排列不太一样的就是这里给的nums数组有重复值,比如nums给[1,1,2],那么如果我按没有重复数的做法来做的话就会有两个[1,1,2],那这里就是不允许的,所以我们要在上一道题的基础上多进行一次去重,就是像组合问题一样进行树层去重,同一树层上的数continue不再选取。去结点的时候,我们把我们遍历到的节点和收集到的结点进行比较,如果这个节点比我们收集到的结点小了,那么我们硬塞进去就不是递增序列了,所以直接continue进行收集下一个结点。
2024-11-19 20:39:40
290
原创 【代码随想录回溯算法|子集问题】
这道题收集结果的条件跟之前的就不一样了,因为之前的题我们在叶子结点中发现满足条件就进行收集,这道题题目要求是要把求子集,所以要把每一次遍历,就是每一个结点进行收集,所以只要我的startindex指向的集合是空集,我已经没有可以继续选择的元素了,那就进行回溯。这里是先加点再从加了点之后的数进行递归,因为我如果先递归,就不方便找到原来字符串末尾,也就不好加点了,所以你只要是正确的串我就赶紧在你背后加个点。笑死,最开始我的递归代码长这样,还老奇怪呢,为啥老是超时hhh。,说明我前一个数也放进了我们的集合里面,
2024-11-16 20:55:00
300
原创 【代码随想录|回溯算法02】
发现有重复的元素,在报错,这道题是要数组里元素的和加起来等于target,因为是组合问题,排列是没有顺序的区别的,也就是说不能走回头路,我赋值i=0,那在每一次递归的时候都会从第一个元素开始选,那么比如我上次选的1,2 这次就会选到2,1就肯定会有重复的数组了,所以这里从startindex开始选的话,我每次就都从这个数往后面选,就可以进行正确的递归了。那我第二个1肯定也能取到组合[1,4]这样不行,就必须要把这个数过掉,这叫树层去重。我的组合是可以包含有[1,1,3]的,这叫树枝去重。
2024-11-10 16:46:01
681
原创 【代码随想录|二叉搜索树04】
这里的思路是如果这个节点的左子树比最小边界小了,那它的左子树肯定更小,但是这个结点的右子树比这个节点大,所以有可能满足这个条件,上面这个节点0的左子树比最小边界小,我就往它的右子树去递归,只要2下面子树满足了,你return root 我就拿结点的左子树(3的左节点)去接住你,就把要删除的点(0)自动的忽略掉了。再比如3往右去递归,4超出边界了,4就往左去递归,返回空,那3的右节点连到nullpstr,就删除掉了4。就是从根节点0开始我的左子树为(0,2)mid就为1,val->left往左去递归。
2024-11-04 20:49:54
364
原创 【代码随想录|二叉搜索树03】
思路就是因为是搜索树,所以如果要找的pq的值在节点的左边,那就遍历左子树,pq值在节点右边就遍历右子树,除了这两种情况,剩下的就是在pq值的中间(不论p更大还是q更大),那我从上往下遍历得到的第一个在他们的值中间的结点那就是最近公共祖先了,就直接把该root返回。这里的思路应该把结点插到叶子结点上的左指针或者右指针就行,只要插入的值比节点小就往左遍历,比节点大就往右遍历,遍历到该插入的位置,也就是终止条件是root==NULL的时候就把这个插入的指针往上返回,那我们要把上一个结点的指向这个新插入的指针。
2024-11-02 19:59:14
285
原创 【代码随想录|二叉搜索树02】
应该要用后序遍历,要先判断左右结点的值之后传入根节点进行判断返回,写的时候这里报错一直,错的原因应该是因为这里的TreeNode*left保存的是有跟p或者q相等的值的结点,所以我在进行判断的时候,是判断保存的left和right的值,也就是这个节点的值是否为空就行,而不是判断的是这个root->left,这个思路就不对。这里用到的是双指针法,感觉思路挺牛的,就是先把最大出现频率设置成0,然后每次进行遍历的时候只要count大于最大频率了,就更新count,更新保存最大频率的数组。
2024-10-28 21:28:36
169
原创 【代码随想录|二叉搜索树】
因为在遍历的时候,遍历到的结点为空后那就说明已经找不到了直接就会直接退出循环返回NULL,但是用两个if语句的话,我就会把root的空节点进行指向val那肯定就报错了,所以得用else if 判断完赋值后我就去看看这个节点是不是为空了,当然空节点就不会进行指向,也就不会报错了。写的时候写的下面这个代码报错了,想了想报错的原因可能是这样会把全部节点遍历, 题目给的那个数据正确结点在左子树,而遍历完左子树result拿到值之后又继续遍历右子树了那就把结果更新为NULL了返回自然也是NULL。
2024-10-26 20:44:20
293
原创 代码随想录|二叉树递归03
题目链接这道题层序遍历感觉挺好理解的,就是在循环体里面把每一层的第一个左边结点保存起来,那最后就能保存到二叉树最底层最左边结点的值了用递归法的话最底层最靠左侧的值不一定是左孩子,也有可能是右孩子,假如在深度最大的那一层没有左孩子,只有一个右孩子,那么这个右孩子从左往右数是第一个值,也是最靠左的值。思路就是要先递归到深度最大,然后再考虑左右孩子的问题。
2024-10-22 21:41:29
572
原创 【王道数据结构|算法时间,空间复杂度】
抓大头T(n)=O(n),O表示同阶,当n趋于无穷T(n)与O(n)之比为常数。算法的时间开销表达式可以只考虑阶数高的部分(抓大头hhh)只需要看循环里面的基本操作分析它的额执行顺序与n的关系就行。算法原地工作:算法所需内存空间为常量S(n)=O(1)普通程序:x的数量级O(x)就是算法空间复杂度S(n)高效率:时间复杂度低,低存储需求:空间复杂度低。事前预估算法时间开销T(n)与问题规模n的关系。2)确定性:对于相同的输入一定要有相同的输出。递归程序:空间复杂度=递归调用的深度。算法:求解问题的步骤。
2024-10-22 11:09:58
175
原创 【代码随想录|二叉树递归法02】
在写的时候直接在while循环里面写while(root->left)root->left=root->left->left,就没通过,好家伙,这么写直接把人二叉树的左节点 都改了(hhh),所以要用临时变量TreeNode* left先指向一个树的结点。在遍历的时候,每到一个节点就先加入到path数组里面,然后进行递归左子树,在遍历到根节点加入到res里面之后就会一个一个pop直到root结点,然后再进行递归右子树,在遍历到根节点加入到res里面之后也会一个一个pop直到root结点。
2024-10-16 19:56:57
832
原创 【代码随想录|二叉树递归法】
这里递归法所谓的前中后序,就是看把根节点的左右指针交换(根)、整个左子树交换(左)还是把整个右子树交换(右)的顺序问题,这里前序遍历和后序遍历的结果其实是一样的,中序遍历要不同一点:比如先把整个左子树交换(左),把根结点的左右指针交换后(中),这个时候交换的右子树其实就是根结点交换过去的左子树(右),所以要用中序遍历的话用(左)(中)(左)才不会错。当左节点为空右节点不为空要返回右节点的值+1,当左节点不为空右节点为空要返回左节点的值+1,左右节点都不为空的时候,就返回最小值+1。
2024-10-09 20:57:34
1092
原创 【代码随想录|二叉树的层序遍历】
最开始depth的值一直不对,因为这里把只要是左节点右节点是空的就计数,那就会把根节点一并记上,正确的思路应该是遍历每一层之前把depth++,如果遇到空节点就直接返回。我滴妈,这个调用用.还是->简直就是运气试出来的(离谱),这里队列里面存的是指针地址,但是队列是当对象来调用的。这里的Node放的是队列里的第一个元素,就是指针了,而且这里的que里面要存储的是指针如果node->children->val那就是往里推的是值了。,那左右结点的如果还有子节点就不会继续遍历,当然就不能通过了。
2024-10-03 18:26:19
622
原创 【代码随想录|栈与队列2】
该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9。最开始一直报错,后来发现是遍历前k个之后没有保存前k的个的最大值。怪不得我看那个测试代码只有加和乘的那个运算测试是通过的hhhh。最开始一直报错我还反复看一点错没有啊...结果是当时写成了。下面是不封装类Myque的方法。,硬给他比较(hhh)
2024-09-26 19:13:18
276
原创 【代码随想录| 栈与队列1】
while(size--)和while(--size)两种循环while(size--)循环会执行size次,而while(--size)会执行size-1次,要看具体需求来用这两种循环。push的要求是把队列的往队列的栈顶添加元素,用栈来实现简直就是老天爷赏饭吃,直接push就完事了。把字符串当栈来用如果和字符不相等就放后面,相等就把这个字符都弹出,最后直接返回字符串。这道消消乐题简直精简得离谱。
2024-09-22 21:15:28
274
原创 【代码随想录字符串2】
这里删除空格的操作快指针指向的是字符串中字母的位置,慢指针指向的是要更新的位置。所以是要快指针是要遍历整个数组,因此判断条件是快指针不等于空的时候。这reverse用着是真的方便。
2024-09-20 19:53:26
188
原创 【代码随想录字符串1】
动态数组里面用reverse 括号里面要用迭代器,不能像静态数组那种直接给下标。好像没啥说的,看看就行。541.反转字符串II。
2024-09-14 21:26:36
144
原创 【代码随想录哈希表2】
就有两组数据一直过不了,后来查了查if else语句才发现, 在if if else 语句里面的else是和最后一个if配对的,也就是说这里我如果三个数相加大于0了我还是会执行else语句把大于0的数存到数组里面,if else if else是互斥的就是三个语句只能执行其中一个。所以这里如果写if if else就过不了了!遍历的是AB数组里面的元素,umap[a+b]是在umap中查找是否有a+b的键,如果有就返回值,如果没有就新加入这个键再返回一个默认的值。
2024-09-14 14:40:11
256
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人