- 博客(56)
- 收藏
- 关注
原创 【代码随想录|150.逆波兰表达式求值、239.滑动窗口最大值、347.前K个高频元素】
【代码】【代码随想录|150.逆波兰表达式求值、239.滑动窗口最大值、347.前K个高频元素】
2025-08-11 10:39:43
128
原创 【代码随想录|232.用栈实现队列、225.用队列实现栈、20.有效的括号、1047.删除字符串中的所有相邻重复项】
【代码】【代码随想录|232.用栈实现队列、225.用队列实现栈、20.有效的括号、1047.删除字符串中的所有相邻重复项】
2025-08-09 14:30:12
247
原创 【代码随想录|151.反转字符串中的单词、55.右旋字符、28.找出字符串找那个第一个匹配的下标、459.重复的子串】
我靠,这个思路有点太牛了,就是把字符串拼接起来,如果字符串有子串,中间就能找到这个字符串。j就直接从i开始,如果从0开始,一是没有必要,二是会访问到【0-i】会是负数。【3,5】:abc就等于s.size()了,返回false,就很妙。是为了验证字符串是否具有周期性,即能否由长度为。看s能否由长度为1,2,3...n/2个字符组成。但如果是abc abc,就找。
2025-08-08 10:04:33
307
原创 【代码随想录|454.四数相加、383.赎金信、15.三数之和、18.四数之和】
这里的count之所以不是直接++,是因为前面a,b两个数相加等于-c-d的次数可能不止一种。去重是必要的,剪枝不是必要的。
2025-08-03 12:22:05
251
原创 【代码随想录|242.有效的字母异位词、202.快乐数、1.两数之和】
因为如果在他之前的话,插入一个数,然后马上检测是不是在集合里,那肯定在(因为刚插入),然后所有数一上来就直接返回false了,哈哈哈哈笑死了,有种孙悟空一边往自己尾巴打一边喊“妖怪”的感觉。这里的nums.insert(sum)一定要在判断if (nums.find(sum)!= nums.end())之后。用了两个集合数据结构,一个用来给其中一个数组去重得到答案作为哈希表,一个用来保存结果。拿数组作为哈希表,而集合数据结构用来保存结果。
2025-08-01 17:18:30
154
原创 【代码随想录|24.两两交换链表、19.删除链表中倒数第N个节点、02.07.链表相交、142.环形链表】
这里因为n如果大于链表长度的话fast在第一个循环遍历结束后会等于空,这个时候fast->next会空指针引用,所以直接先n++比较保险,就不用引用fast指针了。这个我的思路是先数有多少个节点,然后把节点减去倒着数的个数就是正着数的个数,硬给他弄成正着删。
2025-08-01 13:44:43
308
原创 【代码随想录|203.移动链表元素、707.设计链表、206.翻转链表】
为什么不用cur->val直接删除,因为要用前一个节点指向后一个节点,你直接找cur->val找不到前一个节点,所以要用cur->next->val==val才行。最后返回节点不是直接返回head,因为因为头结点head可能也被删除了,所以获取头结点要用dummyhead的下一位来获取707。如果在前面加了前缀,那就不是公用的那个dummyHead了。就是在赋值的时候,因为头结点是大家公用的,所以要直接。
2025-07-31 16:02:18
155
原创 【代码随想录|209.长度最小的数组、59.螺旋矩阵、58.区间和、44.开发商购买土地】
这里的滑动窗口算法思路应该是和暴力一样的,就是把i另外自己定义,还有在维持这个窗口的时候,应该是sum-=nums[i]去掉最左边数,而且不应该break,因为要反复找。这道题我本来想直接用p[i]直接+=而不用presum,但是发现当i变化的时候p[i]也会变化所以需要一个临时变量记录前面的数的和所以需要presum。这里最后返回的不是结果而是条件,笑死,又是经典的if条件里写等于。
2025-07-30 12:06:36
283
原创 【代码随想录二刷|704.二分查找、27.移除元素、977.有序数组的平方】
i 在指向后一个2的位置,如果不i--从1开始的话,就会直接往后遍历i++,漏掉2。双指针感觉就是用fast指针来遍历数组,用slow 指针来更新数组,最后slow指针指向的是更新后的数组。感觉双指针方法就是用i从前往后遍历数组,j是从后往前遍历数组,把大的赋值给新的数组。i 在指向2的位置,把后面的元素往前移,数组变成。size--当然就是移动一次就少一个元素,所以size要--;【0,1,2,2,3】要删的元素是2。这里的i--是因为比如现在是。
2025-07-25 13:17:15
235
原创 LeetCode热题100|128.最长连续序列,283.移动零
这里要求的一个乱序的数组里连续数字的个数,比如【100 ,4,200,1,3,2】里面连续的数字就是【1,2,3,4】返回4可以用排序,就是把他排成【1,2,3,4,100,200】然后挨个遍历,如果是相同的数就跳过,连续的数就计数,不连续的数就重置max_length但是排序因为用到了sort最少也要O(nlogn)的复杂度,所以考虑哈希表O(1)
2025-03-27 20:57:01
348
原创 LeetCode热题100题|1.两数之和,49.字母异位词分组
然后比如我们就开始把键"abc"存在mp容器里面,里面就会放["cab","bca","cba"],emplace_back是vector数组进行调用的,如果发现该数在vector里面那就不加了,不在的话就会往里面添加。哈希表这种方法可以用空间换时间, 把元素设置为key,下标设置成value,一个key可以对应多个value,比如有数组【3,3,3,2】 target为5。不覆盖原下标的话就用map.insert({nums[i],i});3这个元素会有多个下标(0,1,2),收集结果想让他为【2,3】
2025-03-26 19:42:16
306
原创 【代码随想录|动态规划 回文子串】
就只考虑一个,要么考虑前面一个(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
1003
原创 【代码随想录|动态规划 编辑距离问题】
那么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
870
原创 【代码随想录|子序列问题】
而递推公式中加上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
804
原创 【代码随想录|子序列系列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
525
原创 【代码随想录|股票买卖的最佳时机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
857
原创 【代码随想录|买卖股票的最佳时机】
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
547
原创 【代码随想录|打家劫舍198,213,337】
如果要使用递推公式考虑,要使用前一个和前两个数组的值,从0开始可能会超限,所以直接把dp[0]赋值nums[0],dp[1]赋值nums[0]和nums[1]的最大值。敲代码的时候我是按下面这个来敲的,答案是错的,感觉就是因为这里的dp数组是考虑进了之前的房屋的值的,但是我直接加nums的值的话是不会考虑进去的,只有单拎的值。因为相邻的房屋不能偷,所以我第i个的dp值就是考虑我偷当前的房间加上前两个的房间的值和我只偷前一个房间的值进行比较选最大值。就是 当前节点的值+不偷左孩子的金钱+不偷右孩子的金钱。
2025-01-21 12:28:20
581
原创 【代码随想录|动态规划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
329
原创 【代码随想录|完全背包问题】
而外层遍历背包内层遍历物品就不一样了,每一层的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
841
原创 【代码随想录|动态规划背包问题应用】
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
958
原创 【代码随想录|动态规划背包问题】
01背包:n种物品,每种物品只有一个完全背包:n种物品,每种物品有无限个多重背包:n种物品,每种物品的个数各不相同。
2024-12-22 20:15:45
649
原创 【MATLAB课设五子棋教程】(附源码)
设计一个matlab的app是我们期末的答辩内容,我做的这个五子棋主要参考了b站up主唤醒手腕的代码和教程,然后在matlab窗口实现的改到app里实现。最后答辩的实验成绩好像是90+这个app的mlapp文件放在文章最后了,需要自取。
2024-12-21 11:21:31
611
原创 【代码随想录|动态规划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
288
原创 【代码随想录|贪心算法05】
但是如果直接把前一位-1后一位设置成9,如果传入的数是1000的话,结果就会变成0900,所以我设置一个flag来记录当前数要设置为9的地方,后面统一都设置为9了,因为我只要这个数为9,后面的数肯定都是9(没有比9更大的数了)因为从前往后进行修改的话,我后面的数修改了会把一个数-1,会影响已经遍历的的数的大小关系,从后往前遍历的话,我就可以一边遍历一边用修改后的结果。思路就是把从后往前遍历,前面的数比现在的数大的话就把前面的数-1,让后面这个数有选择大的数(9)的可能。我滴妈,这道题的思路好牛啊。
2024-12-10 20:35:27
643
原创 【代码随想录|贪心算法重叠区间问题】
这道题感觉跟上一道题很相像,因为这道题是要去掉重叠区间,让剩下的区间都不重叠,思路就是我们进行先按左区间从小到大进行遍历,如果遍历到重叠的区间我们就要去掉一个重叠区间,所以定义的count++,为了判断后面还有没有区间跟他俩重合,我直接更新区间的右边界来和后面的进行比较。思路就是我们比较这个气球和上一个气球有没有重合的,重合我们一根箭一起就射了,不重合我们就要单独拿根箭射它,每个气球都有左边界points[i][0],和右边界points[i][1],假设有字符串S = "abacabad"
2024-12-06 21:33:02
2041
原创 【代码随想录|贪心算法03】
这里的思路是保存每个站的的加油量减去消耗量(cursum),他为正我肯定就能进行遍历,然后如果一个不小心,你油不够了(cursum<0),那这个点前面的点肯定都不够这个点消耗的了,因为题目说存在解结果是唯一的,那我只要从后面的第一个油是正数的点开始遍历就足够了(按道理我第二个油是正数的点可能也可以,但是题目说只有一个解所以取第一个)在做的时候,发现我这个不对,我最开始想的是我要第一个正数点那,取到了我退出了不就好了,然后报错的一组数据是。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。
2024-12-02 21:18:17
2025
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
782
原创 【代码随想录|回溯算法排列问题】
这道题和46.全排列不太一样的就是这里给的nums数组有重复值,比如nums给[1,1,2],那么如果我按没有重复数的做法来做的话就会有两个[1,1,2],那这里就是不允许的,所以我们要在上一道题的基础上多进行一次去重,就是像组合问题一样进行树层去重,同一树层上的数continue不再选取。去结点的时候,我们把我们遍历到的节点和收集到的结点进行比较,如果这个节点比我们收集到的结点小了,那么我们硬塞进去就不是递增序列了,所以直接continue进行收集下一个结点。
2024-11-19 20:39:40
329
原创 【代码随想录回溯算法|子集问题】
这道题收集结果的条件跟之前的就不一样了,因为之前的题我们在叶子结点中发现满足条件就进行收集,这道题题目要求是要把求子集,所以要把每一次遍历,就是每一个结点进行收集,所以只要我的startindex指向的集合是空集,我已经没有可以继续选择的元素了,那就进行回溯。这里是先加点再从加了点之后的数进行递归,因为我如果先递归,就不方便找到原来字符串末尾,也就不好加点了,所以你只要是正确的串我就赶紧在你背后加个点。笑死,最开始我的递归代码长这样,还老奇怪呢,为啥老是超时hhh。,说明我前一个数也放进了我们的集合里面,
2024-11-16 20:55:00
336
原创 【代码随想录|回溯算法02】
发现有重复的元素,在报错,这道题是要数组里元素的和加起来等于target,因为是组合问题,排列是没有顺序的区别的,也就是说不能走回头路,我赋值i=0,那在每一次递归的时候都会从第一个元素开始选,那么比如我上次选的1,2 这次就会选到2,1就肯定会有重复的数组了,所以这里从startindex开始选的话,我每次就都从这个数往后面选,就可以进行正确的递归了。那我第二个1肯定也能取到组合[1,4]这样不行,就必须要把这个数过掉,这叫树层去重。我的组合是可以包含有[1,1,3]的,这叫树枝去重。
2024-11-10 16:46:01
751
原创 【代码随想录|二叉搜索树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
409
原创 【代码随想录|二叉搜索树03】
思路就是因为是搜索树,所以如果要找的pq的值在节点的左边,那就遍历左子树,pq值在节点右边就遍历右子树,除了这两种情况,剩下的就是在pq值的中间(不论p更大还是q更大),那我从上往下遍历得到的第一个在他们的值中间的结点那就是最近公共祖先了,就直接把该root返回。这里的思路应该把结点插到叶子结点上的左指针或者右指针就行,只要插入的值比节点小就往左遍历,比节点大就往右遍历,遍历到该插入的位置,也就是终止条件是root==NULL的时候就把这个插入的指针往上返回,那我们要把上一个结点的指向这个新插入的指针。
2024-11-02 19:59:14
345
原创 【代码随想录|二叉搜索树02】
应该要用后序遍历,要先判断左右结点的值之后传入根节点进行判断返回,写的时候这里报错一直,错的原因应该是因为这里的TreeNode*left保存的是有跟p或者q相等的值的结点,所以我在进行判断的时候,是判断保存的left和right的值,也就是这个节点的值是否为空就行,而不是判断的是这个root->left,这个思路就不对。这里用到的是双指针法,感觉思路挺牛的,就是先把最大出现频率设置成0,然后每次进行遍历的时候只要count大于最大频率了,就更新count,更新保存最大频率的数组。
2024-10-28 21:28:36
226
原创 【代码随想录|二叉搜索树】
因为在遍历的时候,遍历到的结点为空后那就说明已经找不到了直接就会直接退出循环返回NULL,但是用两个if语句的话,我就会把root的空节点进行指向val那肯定就报错了,所以得用else if 判断完赋值后我就去看看这个节点是不是为空了,当然空节点就不会进行指向,也就不会报错了。写的时候写的下面这个代码报错了,想了想报错的原因可能是这样会把全部节点遍历, 题目给的那个数据正确结点在左子树,而遍历完左子树result拿到值之后又继续遍历右子树了那就把结果更新为NULL了返回自然也是NULL。
2024-10-26 20:44:20
348
原创 代码随想录|二叉树递归03
题目链接这道题层序遍历感觉挺好理解的,就是在循环体里面把每一层的第一个左边结点保存起来,那最后就能保存到二叉树最底层最左边结点的值了用递归法的话最底层最靠左侧的值不一定是左孩子,也有可能是右孩子,假如在深度最大的那一层没有左孩子,只有一个右孩子,那么这个右孩子从左往右数是第一个值,也是最靠左的值。思路就是要先递归到深度最大,然后再考虑左右孩子的问题。
2024-10-22 21:41:29
605
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅