自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 第五十八天| 739. 每日温度、496.下一个更大元素 I

接着便是遍历数组nums2,同上题一样利用单调栈处理,但在 处理栈中所有比当前遍历元素小的元素 内部操作不同,本题在 map中找与栈顶元素(nums2[st.top()])相同的元素,若存在则取该键值对的值value(即栈顶元素在数组nums1的下标)并记录到结果数组result。那么可以看作 先处理数组nums2中每个元素的下一个更大元素(此处理同上题),并用容器map存储(key:nums2[i],value:nums2[j] 其中j > i 且nums2[j] > nums2[i])。

2024-03-18 13:14:20 831

原创 第五十七天| 647. 回文子串、5.最长回文子串、516.最长回文子序列

给你一个字符串s,请你统计并返回这个字符串中的数目。是正着读和倒过来读一样的字符串。是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。动态规划。本题考虑dp数组含义的思路与以往不同。大多数题目是按题目求什么来定义dp数组,但本题如果dp数组定义为,dp[i] :下标i结尾的字符串含回文串的个数,很难找到递归关系。dp[i] 和 dp[i-1] ,dp[i + 1] 看上去都没啥关系。因此要看回文串的性质。

2024-03-16 20:54:59 880

原创 第五十五天| 583. 两个字符串的删除操作、72. 编辑距离

当然要取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});当然要取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 1, dp[i - 1][j] + 1, dp[i][j - 1] + 1});

2024-03-14 22:19:36 1061

原创 第五十四天| 392.判断子序列、115.不同的子序列

从递推公式dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配(就是模拟在s中删除这个元素),即:dp[i - 1][j]。从递推公式dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

2024-03-13 21:09:51 1054

原创 第五十三天| 1143.最长公共子序列、1035.不相交的线、53. 最大子序和

最长公共子序列和还没理解清晰。

2024-03-10 16:48:59 859

原创 第五十二天| 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

动态规划dp数组的定义要考虑到各种情况来定义,以及将处理区间逐步增大的思路。

2024-03-08 11:32:30 634

原创 第五十一天| 309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费

如果i为1,第1天买入股票,那么递归公式中需要计算 dp[i - 1][1] - prices[i] ,即 dp[0][1] - prices[1],此处的 dp[0][1] (即第0天的保持卖出股票状态(状态二))相当于第0天的利润作本金,因此初始为0。那么dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);dp[i][j]:第i天,状态为j,所剩的最多现金为dp[i][j]。

2024-03-07 21:02:08 1015

原创 第五十天| 123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

理解增加dp数组维度来记录不同次的交易,仅在循环过程中将前一次利润当本金处理不能控制交易次数。

2024-03-06 13:46:00 931

原创 第四十八天| 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

从不同角度看待问题,一次买卖还是多次盈利,得出不同动态规划解法。一次买卖的思路(即不考虑中间盈利)更适配此系列问题。

2024-03-06 10:22:21 689

原创 第四十七天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

了解树形动态规划。感受递归+动态规划的设计逻辑:利用系统栈传递dp数组,相当于刷新dp数组关于为什么树形结构,进行动态规划处理比进行暴力法处理节省时间以及为什么不会爆栈,先留下疑问,等理解清晰回头写思路。

2024-03-05 20:13:30 1126

原创 第四十六天| 139.单词拆分、卡码网 56. 携带矿石资源(同多重背包问题)

首先将各种背包问题汇聚成一张图来看:由上图可以清晰的看出各类背包问题的关系。背包问题都可以按照如下五部来逐步分析。确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组每一步都很重要,但确定递推公式和确定遍历顺序都具有规律性和代表性。下面从这两步总结。

2024-03-03 20:26:52 1033

原创 第四十五天| 322. 零钱兑换、279.完全平方数

给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。计算并返回可以凑成总金额所需的。如果没有任何一种硬币组合能组成总金额,返回-1。你可以认为每种硬币的数量是无限的。动态规划。题目中说每种硬币的数量是无限的,可以看出是典型的完全背包问题。dp[j]:从coins中任取硬币,达到总金额为i所需硬币的最小数。

2024-03-03 00:22:51 1150

原创 第四十四天| 卡尔网 52. 携带研究材料(同完全背包)、518. 零钱兑换 II、377. 组合总和 Ⅳ

本题背包(硬币总额)以及物品(硬币)的先后遍历顺序与纯完全背包不同,后者求得装满背包的最大价值是多少,和凑成总和的元素有没有顺序没关系,即:有顺序也行,没有顺序也行!dp[j] 就是所有的dp[j - coins[i]](考虑coins[i]的情况)相加。在处理dp[3]时出现问题,按递推公式dp [3] = dp [2] + dp[1],结果为3,而实际只有2种组合。下标非0的dp[j]初始化为0,这样累计加dp[j - coins[i]]的时候才不会影响真正的dp[j]dp[2] = 2;

2024-03-02 16:27:52 1045

原创 第四十三天| 1049. 最后一块石头的重量 II、494. 目标和、474.一和零

1049 最后一块石头的重量 II有一堆石头,用整数数组stones表示。其中stones[i]表示第i块石头的重量。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为x和y,且x <= y。如果x == y,那么两块石头都会被完全粉碎;如果x!= y,那么重量为x的石头将会完全粉碎,而重量为y的石头新重量为y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回0。动态规划。难点在于:想到尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小。

2024-03-01 19:56:52 967

原创 第四十一天| 卡尔网46. 携带研究材料(同01背包问题)、416. 分割等和子集

其实可以发现如果把dp[i - 1]那一层拷贝到dp[i]上,公式变换成:dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i]);此时dp[j]有两个选择,一个是取自己dp[j] 相当于 二维dp数组中的dp[i-1][j],即不放物品i,一个是取dp[j - weight[i]] + value[i],即放物品i。虽然两个for循环遍历的次序不同,但是dp[i][j]所需要的数据就是左上角,根本不影响dp[i][j]公式的推导。

2024-02-26 00:57:07 838

原创 第四十天| 343. 整数拆分、96.不同的二叉搜索树

给定一个正整数n,将其拆分为k个的和(k >= 2),并使这些整数的乘积最大化。返回你可以获得的最大乘积。动态规划。本题难点在于值n要拆分成几个数乘积最大。dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。首先可以将 i 拆分成两个数相乘,只要 j 从1开始遍历至 i - 1作乘数之一,另一个乘数即为 i - j。考虑dp[i]的定义,dp[i]是 i 拆分成多个乘数得到的最大乘积。因此可以将 i 拆分成多个数相乘,其中一个乘数仍为 j , 另外多个乘数的最大乘积为 dp[i - j]。

2024-02-23 23:06:42 907

原创 第三十九天| 62.不同路径、63. 不同路径 II

一个机器人位于一个m x n网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。从dp[i][j]的定义可以看出,只能有两个方向来推导出来,即dp[i - 1][j]向右走 和 dp[i][j - 1]向下走。

2024-02-22 22:47:06 1657

原创 第三十八天| 509. 斐波那契数、70. 爬楼梯、卡码网 爬楼梯、746. 使用最小花费爬楼梯

(通常用F(n)表示)形成的序列称为。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。给定n,请计算F(n)。动态规划。这是一道简易题,主要用来熟悉动态规划五步曲。定义一个一维dp数组来保存递归的结果。dp[i]的定义为:第i个数的斐波那契数值是dp[i]题目已经给定递推公式:dp[i] = dp[i - 1] + dp[i - 2];题目中也已经给定dp[0] = 0;dp[1] = 1;从递归公式dp[i] = dp[i - 1] + dp[i - 2];

2024-02-21 23:33:22 595

原创 第三十七天| 738.单调递增的数字、968.监控二叉树

738.单调递增的数字。

2024-02-20 16:44:18 1144

原创 第三十六天| 435. 无重叠区间、763.划分字母区间、56. 合并区间

给定一个区间的集合intervals,其中。返回需要移除区间的最小数量,使剩余区间互不重叠。贪心法。和原理类似。按照左边界排序,从左向右记录多余交叉区间的个数。或者按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间的个数。此图先按右边界排序,之后记录非交叉区间的个数还是有技巧的。取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的。

2024-02-19 22:35:26 488

原创 第三十四天| 860.柠檬水找零、406.根据身高重建队列 、452. 用最少数量的箭引爆气球

860.柠檬水找零。

2024-02-17 17:21:45 979

原创 第三十三天| 1005.K次取反后最大化的数组和、134. 加油站 、135. 分发糖果

那么让i从0开始累加remainder[i],和记为curRemainder,一旦curRemainder小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curRemainder。情况二:gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。如果跑了一圈,中途没有断油,而且最后油量大于等于0,说明这个起点是ok的。

2024-02-16 21:26:38 1017

原创 第三十二天| 122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II

通常的思维:选一个低的买入,再选个高的卖。如果想到最终利润是可以分解的,即把利润分解为每天为单位的维度,此题就简化为选取递增差值累加。要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。针对于一的特殊情况,可以统一处理,即:移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不考虑是不是终点的情况。

2024-02-15 23:49:27 676

原创 第三十一天| 455.分发饼干 、376. 摆动序列、53. 最大子序和

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子i,都有一个胃口值g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j,都有一个尺寸s[j]。如果,我们可以将这个饼干j分配给孩子i,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。贪心法。局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。小饼干先喂饱小胃口。

2024-02-14 23:34:48 790

原创 第三十天| 51. N皇后

验证row行col列摆放皇后合法性:参数当前行列值,当前棋盘以及皇后个数。终止条件:如果当前处理行数row等于n时说明皇后已全部摆放完毕,将当前棋盘摆放情况chessboard存放到结果集result中。单层搜索逻辑:从下标0开始循环处理每个二维坐标位置,若当前行row当前列col存放皇后合法则摆放皇后,递归处理,最后回溯。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。的棋盘上,并且使皇后彼此之间不能相互攻击。的棋子放置方案,该方案中。分别代表了皇后和空位。

2024-02-09 01:35:10 627

原创 第二十九天| 491.递增子序列 、46.全排列、47.全排列 II

给你一个整数数组nums,找出并返回所有该数组中不同的递增子序列,递增子序列中。你可以按返回答案。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。回溯法。终止条件:如果节点集node中数据个数大于1则将此节点集写入结果集。(此处不可返回,要继续执行下续操作,因为要处理符合条件的各个节点)单层搜索逻辑:定义set容器记录本层数字使用情况。循环从startIndex开始,如果当前处理数字在容器set中能查询到则说明此数字本层搜索已经使用过。

2024-02-08 00:55:37 936

原创 第二十八天| 93.复原IP地址 、78.子集、90.子集II

分清子集问题和组合问题、分割问题的的区别:子集是收集树形结构中树的所有节点的结果。组合问题、分割问题是收集树形结构中叶子节点的结果。

2024-02-06 18:30:59 791

原创 第二十七天| 39. 组合总和 、40.组合总和II、131.分割回文串

给你一个的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的 所有,并以列表形式返回。你可以按返回这些组合。candidates中的数字可以。如果至少一个数字的被选数量不同,则两种组合是不同的。对于给定的输入,保证和为target的不同组合数少于150个。candidates和几乎相似,区别在于数组中的数字可以无限次数选取,则只需要将单层搜索逻辑中递归处理中传递的参数startIndex改为i,这样同一数字可重复取。

2024-02-06 01:26:55 725

原创 第二十五天| 216.组合总和III、17.电话号码的字母组合

找出所有相加之和为n的k返回所有可能的有效组合的列表。该列表不能包含相同的组合两次,组合可以以任何顺序返回。回溯法。先设计全局变量结果集result,路径集path。终止条件:在路径path 满足条件长度k后,判断当前sum是否满足targetSum,若满足则添加到容器result内。单层搜索逻辑:从startIndex开始循环添加到路径path中,再递归处理,最后再回溯。

2024-02-04 01:44:53 483

原创 第二十四天| 77. 组合

由上图可以看出n相当于树的宽度,k相当于树的深度。每次搜索到了叶子节点就找到了一个结果。故终止条件:组合长度满足条件k时则将此次组合写入结果中。单层搜索逻辑:循环过程中,添加区间中的一个值到组合,递归处理,将值移除组合。对单层搜索逻辑剪枝处理。如果for循环选择的起始位置之后的元素个数已经不足需要的元素个数,那么就没有必要搜索了。每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围。把回溯法的搜索过程抽象为树形结构。

2024-02-03 00:17:54 359 1

原创 第二十三天| 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

给你二叉搜索树的根节点root,同时给定最小边界low和最大边界high。通过修剪二叉搜索树,使得所有节点的值在中。修剪树改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。可以证明,存在。所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。递归法。终止条件:若当前节点为空则返回空。单层递归逻辑:如果当前节点val值大于最大区间值,递归处理其左子树并返回。如果当前节点val值小于最小区间值,递归处理其右子树并返回。

2024-02-02 20:26:58 733

原创 第二十二天| 235. 二叉搜索树的最近公共祖先 、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(递归法。终止条件:如果当前节点为空,则说明查找失败,返回空。如果当前节点val值在两目标节点val值之间则说明查找成功,返回当前节点。

2024-02-01 01:56:56 1296 1

原创 第二十一天| 530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

给你一个二叉搜索树的根节点 root ,返回树中任意两不同节点值之间的最小差值。差值是一个正数,其数值等于两值之差的绝对值。中序遍历递归法。设置两个成员变量pre记录上一个节点,result记录最小差值。在pre不为空的情况处理当前递归节点,比较当前节点 val值和前一个节点pre的val值的差值与result,更新result和pre。中序遍历迭代法。在中序遍历迭代写法的基础上简单修改循环中出栈元素后的处理逻辑:改为更新最小差值和记录节点中序遍历统一迭代法。

2024-01-30 23:16:04 880 1

原创 第二十天| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为null 的节点将直接作为新二叉树的节点。中序递归遍历,记录左右子树递归返回结果,判断当前节点时遇到当前节点root的val值是否小于前一个节点pre的val值,是则返回false。单层递归逻辑:先寻找数组中最大值的下标并创建节点root,按此下标分割数组,递归处理分割后的数组作为root节点的孩子节点。单层递归逻辑:创建新节点,其val值为两二叉树节点val值之和,并处理两二叉树左右子树作为新节点的左右子树。

2024-01-30 00:10:01 941 1

原创 第十八天| 513.找树左下角的值、112. 路径总和、113.路径总和ii、106.从中序与后序遍历序列构造二叉树、105.从前序与中序遍历序列构造二叉树

关键点:不要误以为一直向左遍历的就是最底层的节点,最底层的叶子节点有可能在右子树中。考虑到要求节点的深度,采用前序遍历,这样首个遍历的最深的叶子节点就是目标节点。单层递归逻辑:将非空孩子节点进行处理,参数count先减去孩子节点的value值,回溯时加上value值。理论知识:以 后序遍历数组的最后一个元素为切割点,先切中序遍历数组,根据中序遍历数组,反过来再切后序遍历数组。唯一的区别:栈中存储元素类型改为键值对,不仅存储节点还要存储根节点到记录节点的路径之和。,请找出该二叉树的最底层最左边节点的值。

2024-01-28 14:01:49 494

原创 第十七天| 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和

单层循环逻辑:通过当前节点的左子树高度和其右子树高度的差值来判断以当前传入节点为根节点的二叉树是否是平衡二叉树。分别求出其左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1做标志,表示已经不是二叉平衡树。单层循环逻辑:递归处理左右孩子节点,判断当前节点左孩子是否为叶子节点,若是则用其值作为左孩子节点返回值(而非作为当前节点返回值),最后将左右孩子节点返回值相加作为当前节点的返回值。,按任意顺序,返回所有从根节点到叶子节点的路径。给定一个二叉树,判断它是否是高度平衡的二叉树。

2024-01-27 01:03:58 359

原创 第十六天| 104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

递归三部曲,逐步理解单层递归逻辑的考虑思路。

2024-01-26 15:55:44 636 1

原创 第十五天| 二叉树的层序遍历、226.翻转二叉树、101. 对称二叉树

每次循环记录当前队列元素个数(即树上一层节点个数),循环出栈并写入数组vec,同时将其非空孩子节点入队,最后将数组vec写入数组result。给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。层序遍历,在单层遍历时除本层末尾节点next指向null,其余节点next指向队头节点。层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是则放进result数组中。,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。,返回其节点值的 层序遍历。以内的答案可以被接受。

2024-01-24 23:55:18 1157

原创 第十四天| 二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法

了解标记法,通过设置指定的标志标记要处理的元素,统一化遍历和处理。

2024-01-23 18:55:46 430 1

原创 第十三天| 239. 滑动窗口最大值 、347.前 K 个高频元素

为降低时间复杂度,采取固定大小为K的小根堆,当然要自定义比较器。最后将剩下的高频元素存储到容器vector中返回。主函数中,先将前k个元素存入MyQueue对象中,用容器存储第一个最大值,之后从k+1个元素开始遍历数组,每次出队窗口最前面的元素,入队窗口后面一个元素,再得到最大值存入容器。保持如上规则,每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。的滑动窗口从数组的最左侧移动到数组的最右侧。自定义队列MyQueue,存放有可能成为窗口里最大值的元素。,请你返回其中出现频率前。

2024-01-22 22:45:52 783

空空如也

空空如也

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

TA关注的人

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