- 博客(54)
- 收藏
- 关注
原创 4.24 log | 链表内指定区间反转,合并两个排序的链表,合并k个已排序的链表
全链表反转用递归几行代码就能解决,而这题是在限定区间里反转所以用栈来做代码更简洁,把链表划分为区间外左边,区间,区间外右边,三部分,只操作其中区间部分,首先求出链表到达区间的前一位left,然后用stack储存区间内指针,并求出区间外后边第一位right,然后再用while循环,left指向st.top()依次反转区间内指针指向,最后输出表头,注意不能输出head,head可能被反转到后面。总结,用栈来处理反转区间,以及左右两边衔接处的处理。
2024-04-24 10:31:20
297
原创 3.15 log | 1047. 删除字符串中的所有相邻重复项,20. 有效的括号,150. 逆波兰表达式求值,239. 滑动窗口最大值,347.前 K 个高频元素
这道题用字符串string模拟栈的思想,如果字符串此时为空或者字符串末尾元素不等于此时要加入的元素时,元素就加入字符串,如果字符串此时不为空而且即将加入的元素等于字符串末尾元素时,字符串就要把相同的元素pop掉。
2024-03-15 20:30:59
434
1
原创 3.12 log | 42. 接雨水,84.柱状图中最大的矩形
接雨水用单调栈来做,具体思路是求出体积的高和宽,stack容器储存的是数组下标,单调栈单调递增,遍历到元素比栈顶元素大时,此时栈顶元素为容器的低,元素为右侧的边,记录此时栈顶数组下标对应的值作为底边,然后pop掉,如果栈不为空,那么此时的栈顶元素对应的值就是左侧边,然后根据木桶效应取短边减去底边高,而体积的宽为i-stack.top()-1,计算得到体积值,最后sum累加体积值。具体思路是单调栈单调递减,当元素比栈顶元素小时,元素作为右边,此时的栈顶元素作为右边,st.pop(),现在的栈顶元素作为左边。
2024-03-13 09:57:38
424
原创 3.11 log | 739. 每日温度,
这道题是运用了单调栈,单调栈就是栈里面的元素都是单调的,当新来的元素大于栈顶,栈顶要先弹出然后再加入新的元素成为栈顶,这道题栈里面的元素时时元素的数组下标,新进的元素都是和下标对应的数组进行比较,注意while循环里面要先判断栈是否为空再进行下一步判断,防止内存泄漏。整体代码和每日温度类似,对于首尾相连的环形数组,遍历长度扩展为两倍size,循环内下标为i%nums.size(),栈里储存的元素为变化后的下标。
2024-03-12 11:24:14
404
原创 3.10 log | 647. 回文子串
这道题dp[i][j]的含义为【i,j】区间内最长回文子序列长度,所以递推公式为if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2,else dp[i][j]=max(dp[i+1][j],dp[i][j-1]),初始化要注意记得初始化dp[i][i]为1。
2024-03-10 20:47:02
400
原创 3.9 log | 115. 不同的子序列,583. 两个字符串的删除操作,72. 编辑距离
这道题用删减的思路来做就是这种写法,dp[i][j]的含义就是以i-1为结尾,j-1为结尾的word1,word2字符串,要相等要减去的最少步数,所以递推公式为if(word1[i-1]==word2[j-1]) dp[i][j]=dp[i-1][j-1],因为相等了所以不需要删减元素,else dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1),否则就删掉word1[i-1],所以dp[i][j]=dp[i-1][j]+1,同理删掉word2[j-1]
2024-03-09 20:11:43
375
原创 3.7 log | 674. 最长连续递增序列,718. 最长重复子数组,1143.最长公共子序列,1035.不相交的线,53. 最大子序和
dp[i]的含义为以nums[i]为结尾的最大子数组和,初始化dp[0]=nums[0],result=dp[0],递推公式为dp[i]=max(dp[i-1]+nums[i],nums[i]),如果dp[i-1]<0,dp[i]从当前位置重新开始累加。这道题要求最长公共子序列长度,上一题是连续,这一题是离散的,所以dp[i][j]的含义有所变化,dp[i][j]表示在[0,i),[0,j),所以也有效避免了字母先后顺序不一致的情况,区间上最长公共子序列的长度值,初始化dp数组为0。
2024-03-08 09:07:41
345
原创 3.6 log | 309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费,300.最长递增子序列
这道题dp[i]的含义为以nums[i]结尾的最长子序列长度,dp[i][的初始化为全为1,因为子序列至少长度为1,递推公式为dp[i]=max(dp[i],dp[j]+1),i从前向后遍历,j在[0,i)的范围内遍历,每一个dp[i]都要比较,选出最大值返回。这道题添加了冷冻期,卖了的第二天不能交易,处于冷冻期,所以把一天分为四个状态,dp[i][0]表示当天卖出,dp[i][1]表示卖出天数>1,dp[i][2]表示持有状态,dp[i][3]表示当前处于冷冻期,这四种状态包括了所有可能状态。
2024-03-07 09:29:50
562
原创 3.5 log | 337.打家劫舍 III,121. 买卖股票的最佳时机,122.买卖股票的最佳时机II,123.买卖股票的最佳时机III
这道题用贪心做很简单,一次遍历,用最小值依次相减,求最大差值,用动态规划做,dp[i][0]表示这天不持股最大盈利,dp[i][1]表示这天持股最大盈利,dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]),dp[i][1]=max(dp[i-1][1],-prices[i]),因为只能买卖股票一次,所以当日买入直接是-prices[i]这道题相当于总结前面几题的规律,规律在奇偶性上,奇数就是买进,偶数就是卖出。
2024-03-06 16:45:16
332
原创 3.4 log | 279.完全平方数,139.单词拆分 ,198.打家劫舍,213.打家劫舍II
这道题和零钱兑换那道题的思路可以说是一模一样的,背包的容量为n,物品的重量为i^2,价值为1,所以递推公式为dp[j]=min(dp[j],dp[j-i^2]+1),初始化为dp[0]=0,其余元素为n,因为dp[j]不存在无解的情况,最大就为n。
2024-03-05 09:06:13
322
原创 3.3 log | 474.一和零,518.零钱兑换II,377. 组合总和 Ⅳ,322. 零钱兑换
这道题也能转化为01背包问题,以往题目,物品包括重量,价值两个属性,背包包括容积一个属性,以前题目,容积以及重量都是一维的,而这道题,物品的重量为x,y两个维度,价值是1,添加一个加一,背包的容积也变为x,y两个维度,所以dp[i][j]=max(dp[i][j],dp[i-zeroNum][j-oneNum]+1),数组初始化是,dp[0][0]=0,在创建数组的时候已经初始化了,故可以省略。
2024-03-04 10:16:32
475
原创 3.2 log |416. 分割等和子集,1049.最后一块石头的重量II,494.目标和
public:i++){j--){这道题和上一题类似,求出两两粉碎后,剩下最小的石头,其实就是上一题的变种,看是否分成两堆的石头能相互抵消,如能抵消就是返回0,如果抵消不了就是接近dp[target]的两堆石头相减(sum-dp[target]-dp[target])
2024-03-03 13:06:00
392
原创 3.1log | 62.不同路径,63. 不同路径 II,343. 整数拆分,96.不同的二叉搜索树
这道题和台阶题类似,到达下一个点是由上两个点决定的,即该点左侧的点和该点上面的点,到达该点的路径总和为dp[i][j]=dp[i-1][j]+dp[i][j-1],dp数组初始化为整个二维数组的上边界和左边界,因为是从左上角出发,行进方向只有向右和向下,所以遍历顺序为从左到右从上到下,用两层for从左到右一层一层遍历,注意末尾点是dp[m-1][n-1],不是dp[m][n]vector数组未初始化,默认全为0。
2024-03-01 21:04:05
408
原创 2.29log | 968.监控二叉树,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯
这道题代码和斐波那契数列差不多,首先要找规律得出递推公式,dp[n]下标的含义就是n个台阶,走完n个台阶,最后一步只有两个选择,就是一次踏一步还是一次踏两步,一次踏一步,那么之前一定是走了n-1个台阶,所以有dp[n-1]种方法,同理踏两步,走完n步台阶方法一定是dp[n-2],所以走完n步台阶方法为dp[n-1]+dp[n-2],递推公式为dp[n]=dp[n-1]+dp[n-2];这道题用递归来做很简洁,也很巧妙,F(1)和 F(0)在最开始防止数据溢出的条件中。
2024-03-01 09:00:58
521
原创 2.28 log | 406.根据身高重建队列,452. 用最少数量的箭引爆气球,435. 无重叠区间,763.划分字母区间,56. 合并区间,738.单调递增的数字
本题值得注意的一点是对people数组的从大到小排序以及身高相等时又降序,排完序之后要新建一个vector数组储存调序后的vector数组,因为如果在原基础上调序对可能会对同一组序列进行反复调序,小的往前调不会影响大的排序,大的是从大到小依次调不会产生大的往后调的情况,都是往前调。
2024-02-29 08:55:43
341
原创 2.27 log 860.柠檬水找零
由于只有三种情况,所以用if else枚举就能解答,首先给5,five就++,给10,ten就加加,five就--,给20就两种情况,有ten,ten--,five--,没ten,five-=3,最后循环内判断five是否小于0,小于0了就返回false,全部遍历完了就返回true。
2024-02-28 09:00:04
365
原创 1.6 log 134. 加油站,135. 分发糖果
这道题的贪心就是如果加油和耗油和为负,则直接从下一个加油站出发,因为前面的累加都只能为负,之前每次加油和耗油和都为正,对下一个加油和耗油都是正向增益,所以前面累加只能为负,只能选取下一个节点为出发节点,如果选到最后一个节点都不满足条件,则,必定是总耗油量大于加油量,返回-1这是这道题的暴力解法,for循环适合从头到尾遍历,while循环适合环形遍历,代码巧妙的一点是利用取余实现数组的闭环循环。
2024-02-27 12:45:56
346
原创 1.5 log 1005.K次取反后最大化的数组和
下面这种解法时间复杂度更低,首先对数组的绝对值从大到小排序,然后遍历数组,如果nums[i]为负同时k不为0,则从左到右依次对负数取绝对值,如果k为0了则累加数组就行,如果nums[i]为正了,则先判断k的奇偶,如果为偶数直接累加,如果为奇数则对数组末数值去绝对值,然后累加。
2024-01-05 20:22:26
366
原创 12.14 log 376. 摆动序列,53. 最大子序和
这个版本省略了vector数组,用整型result来记录累加的最大值,count来累加,一旦数组累加值为负时,该数组对后序数组的累加值毫无贡献,摒弃当前数组,count清零,但是result并不会清零,会记录之前的正向累加值,count从下一位开始重新累加。贪心贪的就是结果越加越大,前面累加结果为负数时直接抛弃,sum从零开始重新累加,所有累加的结果都要记录进vector数组,最后排序,返回最大值。
2023-12-14 19:54:35
507
原创 12.13 log
局部最优就是大饼干喂给胃口大的,举不出反例就是全局最优,要先对饼干数组和胃口数组 排序,然后外层循环里面放置胃口,里面放置饼干,满足饼干大于等于胃口饼干才递减,不管满不满足胃口都要递减。
2023-12-14 08:32:00
413
原创 12.13 log
递归的参数为传入的9X9棋盘,返回值为bool类型,因为本题只要求遍历出一个结果就返回,所以递归要有返回值;递归的终止条件没有,因为如果本题无解那么直接最在任何合适数字后return false了,不会向下递归;判断是否符合条件,注意是看在哪个九宫格,注意审题。
2023-12-13 15:09:02
359
原创 12.11 log
递归的参数为皇后的个数,递归的行数,创建的棋盘,递归的返回值无;单层递归逻辑为用for循环横向遍历,横向遍历的宽度为n,row表示递归的深度,和之前一些题目startIndex类似,进入for循环先判断是否符合要求,如符合要求chessBoard[row][i]=‘Q’,直接进入下一层递归,递归之后在回溯,chessBoard[row][i]=‘.’。判断是否符合要求的函数,可以适当剪枝,只用考虑该位置同一列,上面部分否有'Q',以及该位置上半部分左右两斜线上是否有'Q'。
2023-12-12 15:48:55
352
原创 12.10 log
这道题我是用set容器来记录是否元素是否用过,其实也可以用bool类型的vector容器来记录递归参数为传入的数组,由于记录是否元素是否用过的used数组,无返回值;递归的终止条件为如果path长度与传入数组长度相等时,result记录path并返回;
2023-12-10 21:34:39
349
原创 12.05 log
public:这道题是递增子序列,我们不能一上来就排序,会打乱原本的顺序,和子集那题不一样不能先排序去重,要用set容器来去重。递归的参数为传入的数组,遍历的起始下标startIndex,无返回值;递归的终止条件无,这道题相当于也是和子集那题一样要遍历每一个节点,不同就要去一个递增的序列,所以要求path的集合长度大于1;
2023-12-10 09:38:42
378
原创 12.05 log
这道题和之前的组合切割不同,它需要遍历树形结构的每一个节点,递归的终止条件也可以省略。递归的参数为传入的数组,遍历的起始下标startIndex;终止条件为当startIndex等于数组长度时return,因为本题是要遍历数的每一个节点,不涉及剪枝等操作而且当startIndex等于数组长度时不会进入for循环,也会被return掉,所以可以省略终止条件;
2023-12-05 16:26:16
351
原创 12.04 log
递归的单层逻辑为,首先用for循环横向遍历,用startIndex和i来分割字符串,并判断是否符合要求,如符合要求在在该子串后面插入' . ',pointSum++,如果不符合要求则直接break,这里和上一题分割回文串不一样,上一题是如果目前不是回文子串,后面可能会出现符合要求的,而这道题不符合要求则后面子串肯定都不符合要求,要么有非法字符,要么大于255,然后进入下一层递归,startIndex传入的值为i+2,因为有添加了一个' . ',然后回溯。
2023-12-04 15:50:31
348
原创 12.02 log
首先得写一个判断是否是回文串的函数,返回值为bool类型,参数为字符数组,起始下标,终止下标,然后写递归函数,返回值无,递归参数为字符数组,startIndex横向遍历的起始下标;递归单层的逻辑为,用for循环横向遍历,进入循环后首先要判断startIndex和i之间截取的字符串是否是回文子串,如果是path记录该回文串,继续进行下一次递归,如果不是则continue,跳过此次i值循环,进入下一个i+1值横向遍历,递归回溯同一层startIndex都是相等的,即起始位置都是相等的。
2023-12-02 21:20:21
350
原创 11.29 log
终止条件,当数字和大于等于目标和时返回,当梳子和等于目标和时,result记录该path;单层递归逻辑为,用for循环横向遍历,i的起始值为startIndex, path记录该点数组的值,然后递归,传入startIndex的值为i,因为一个数字可以重复取多次,Sum传入Sum+节点值,因为是形参,所以递归return之后自动回溯,path弹出节点值。单层遍历逻辑为先表示出单层的letter,然后用for循环横向遍历,用path记录字符,然后递归,后回溯,path弹出字符。
2023-11-29 11:20:58
357
原创 11.28 log
这是组合问题的剪枝优化,就优化了一行代码,因为要找的组合大小,在递归过程中如果startIndex后面的数组大小加当前记录的path大小小于组合大小,这部分递归就没有必要进行,具体就是:此时已记录的大小为path.size(),后面至少还应有的空间为k-path.size(),而此时留有的的空间为n-startIndex+1,所以现留有的空间应至少大于理论上的空间,所以n-startIndex+1>=k-path.size(),所以,startIndex<=n+1-k+path.size()。
2023-11-28 15:57:49
342
原创 11.27 log
递归参数是根节点,无返回值,终止条件是当递归到空时就返回,递归内部逻辑为右中左遍历,一个pre指针记录前一个节点的累加值,初值为0,中序的处理逻辑为当前节点值等于当前节点值加上pre,pre又等于累加后的节点值,作为下一次递归的前面节点值累加。这道题和由中序后序数组构造二叉树类似,我的区间划分是左闭右开。递归参数为给定的数组,左闭区间,右开区间,终止条件为当左区间值和右开区间值相等时就返回,递归内部逻辑为前序遍历,子树root值为数组mid的值,再依次向左向右遍历。
2023-11-27 16:28:18
335
原创 11.26 log
递归参数为根节点,删除的目标值,返回值为根节点,终止条件为当递归到空节点时返回空,当递归到与目标值相等时,判断root左右节点的情况,分为四种,一,root为叶子节点,直接删除root返回NULL;四,root两个子节点都不为空,可以root指向root->right,然后右子树的最左叶子节点的左节点指向root->left,删除root,递归内部逻辑为当root值大于key,向左递归,并用root->left接住返回值,当root值小于key时反之则反,最后返回值为每一层的root。
2023-11-26 11:08:07
391
原创 11.24 log
这是比较繁琐的方法,递归参数为根节点,插入值,返回值为插入后的根节点,终止条件为到递归到空节点时,插入节点并返回,递归内部逻辑为如果root值大于val就向左遍历,如果root值小于val就向右遍历,不为空就继续往下,为空就插入节点,最后返回节点。这是简化后的方法,用root->left,root->right接住返回回来的node,减少了代码量,代码更简洁。
2023-11-24 10:45:27
466
1
原创 11.23 log
递归参数为根节点root,目标节点p,q,递归返回值为最近公共祖先,递归终止条件为遇到空就返回,递归内部逻辑为当root大于p,q时往左递归,当root小于p,q时往右递归,如果roor在p,q中间,则root为最近公共祖先,返回root,然后一路返回上去。递归的参数为根节点,两个指定节点,返回值为空节点或者root,终止条件为当递归到空节点或者与指定节点时相同时终止,递归内部逻辑为后序遍历,由下往上回溯,左节点不为空返回左节点,右节点不为空返回右节点,都不为空返回root,都为空返回NULL。
2023-11-23 18:24:11
18
原创 10.25 log
这版代码比上版代码运行起来效率更高,利用一次二叉搜索树的中序遍历就能搜索出二叉树的众数,这个方法巧在运用了两个count,一个count,一个maxCount,当前后指针相等时,count增加,不等count打回原形,等于1,maxCount根据count而后赋值,count等于maxCount时,result数组添加,count大于macxCount数组时,清空数组,再添加,同时maxCount等于此时的count。
2023-10-26 11:10:48
35
原创 10.24 log
二叉搜索数用中序遍历输出的节点是有序递增数列,所以先用中序遍历节点,用数组记录,再怕判断数组是否为递增数列,即可判断是否为二擦搜索数这是运用了双指针法,利用中序遍历,判断前一个节点值和现在节点的大小关系。
2023-10-25 12:47:55
35
原创 10.23 log
递归参数为传入的根节点和目标值,返回值为TreeNode* 型的result,递归终止条件为节点为空就返回,递归内部逻辑为如果节点的值为目标值就返回该节点,并用result记录该节点,遍历顺序为中左右,在result为空的情况下才无往下遍历,如找到目标节点就会一直返回该节点。利用二叉搜索树特性,提高搜索效率,左子树小于根节点,右子树大于根节点,递归返回过程中result值不会改变,因为不会进入另一条递归分支。
2023-10-24 08:50:44
49
1
原创 10.19 log
和之前中序后序构建二叉树一个思路 ,递归参数为:传入的数组,分割后的数组左右下标。开闭原则依然是左闭右开,递归终止条件是数组为空,返回NULL,递归内部逻辑就是先找root,即数组内最大值,然后把数组分割为两左右部分,左右子树再递归两个数组。递归返回值为Treenode*型的node。
2023-10-20 12:29:53
51
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人