自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录算法训练营第60天 | 84.柱状图中最大的矩形

60天的训练营完结撒花~刚开始参加的时候觉得,和自己学也没什么区别嘛,但是随着自己开始打卡记录自己的学习进程,越来越发现其实对于不够自律的人来说,有一个明确的目标是还不错的一个选择,不然会一直在路上,然后放弃掉,断断续续的学习,不如持续不断的学习效率高。如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),rigt(6),但是得不到 left。因为 将 8 弹出之后,栈里没有元素了,那么为了避免空栈取值,直接跳过了计算结果的逻辑。

2024-02-26 10:30:00 2000 1

原创 代码随想录算法训练营第59天 | 503.下一个更大元素II 42. 接雨水

目录503.下一个更大元素II 💡解题思路💻实现代码42. 接雨水 💡解题思路暴力解法双指针优化单调栈准备工作💻实现代码题目链接:503.下一个更大元素II给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。示例 1:提示:将范围变成2*n,用i%n来表示第i个元素。42. 接雨水 题目链接:42.

2024-02-25 10:30:00 939

原创 代码随想录算法训练营第58天 | 739. 每日温度 496.下一个更大元素 I

题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。在遍历nums2的过程中,我们要判断nums2[i]是否在nums1中出现过,因为最后是要根据nums1元素的下标来更新result数组。

2024-02-24 16:30:00 1672

原创 代码随想录算法训练营第57天 | 647. 回文子串 516.最长回文子序列 动态规划总结篇

确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组。

2024-02-24 10:30:00 700

原创 代码随想录算法训练营第56天 |583. 两个字符串的删除操作 72. 编辑距离 编辑距离总结篇

t中找到了一个字符在s中也出现了相当于t要删除元素,继续匹配给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数:当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。这里可能有同学不明白了,为什么还要考虑 不用s[i - 1]来匹配,都相同了指定要匹配啊。

2024-02-23 16:30:00 855

原创 代码随想录算法训练营第55天 |392.判断子序列 115.不同的子序列

t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];其实这里 大家可以发现和。

2024-02-23 10:30:00 882

原创 代码随想录算法训练营第53天 |1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划

而是dp[6]。在回顾一下dp[i]的定义:包括下标i之前的最大连续子序列和为dp[i]。那么我们要找最大的连续子序列,就应该找每一个i为终点的连续最大子序列。所以在递推公式的时候,可以直接选出最大的dp[i]。

2024-02-22 16:30:00 2246

原创 代码随想录算法训练营第52天 |300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

目录300.最长递增子序列💡解题思路💻实现代码674. 最长连续递增序列💡解题思路💻实现代码718. 最长重复子数组💡解题思路💻实现代码300.最长递增子序列题目链接:300.最长递增子序列给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。示例 1:输入:nums = [

2024-02-22 10:30:00 721

原创 代码随想录算法训练营第51天 |309.最佳买卖股票时机含冷冻期 714.买卖股票的最佳时机含手续费 总结

股票只能买卖一次,问最大利润。

2024-02-21 16:30:00 1058

原创 代码随想录算法训练营第50天 |123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

例如 dp[i][1] ,并不是说 第i天一定买入股票,有可能 第 i-1天 就买入了,那么 dp[i][1] 延续买入股票的这个状态。一定是选最大的,所以 dp[i][1] = max(dp[i-1][0] - prices[i], dp[i - 1][1]);选最大的,所以 dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);那么dp[i][1]究竟选 dp[i-1][0] - prices[i],还是dp[i - 1][1]呢?

2024-02-21 10:30:00 749

原创 代码随想录算法训练营第49天 |121. 买卖股票的最佳时机 122.买卖股票的最佳时机II

那么第i天持有股票即dp[i][0],如果是第i天买入股票,所得现金就是昨天不持有股票的所得现金 减去 今天的股票价格 即:dp[i - 1][1] - prices[i]。同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来。

2024-02-20 16:30:00 919

原创 代码随想录算法训练营第48天 | 198.打家劫舍 213.打家劫舍II 337.打家劫舍III

目录198.打家劫舍 💡解题思路💻实现代码213.打家劫舍II 💡解题思路💻实现代码337.打家劫舍III💡解题思路💻实现代码题目链接:198.打家劫舍你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃

2024-02-20 10:30:00 643

原创 代码随想录算法训练营第46天 | 139.单词拆分 关于多重背包,你该了解这些! 背包问题总结篇!

关于这几种常见的背包,其关系如下:通过这个图,可以很清晰分清这几种常见背包之间的关系。在讲解背包问题的时候,我们都是按照如下五部来逐步分析,相信大家也体会到,把这五部都搞透了,算是对动规来理解深入了。确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);

2024-02-19 16:30:00 1063

原创 代码随想录算法训练营第45天 | 70. 爬楼梯 (进阶) 322. 零钱兑换 279.完全平方数

凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j](考虑coins[i])既然递归公式是 dp[i] += dp[i - j],那么dp[0] 一定为1,dp[0]是递归中一切数值的基础所在,如果dp[0]是0的话,其他数值都是0了。本题呢,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]

2024-02-19 10:30:00 2018

原创 代码随想录算法训练营第44天 | 完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ

dp[0]=1还说明了一种情况:如果正好选了coins[i]后,也就是j-coins[i] == 0的情况表示这个硬币刚好能选,此时dp[0]为1表示只选coins[i]存在这样的一种选法。所有可能的组合为: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1)因为递推公式dp[i] += dp[i - nums[j]]的缘故,dp[0]要初始化为1,这样递归其他dp[i]的时候才会有数值基础。而不会出现{5, 1}的情况。

2024-02-07 10:53:04 1023

原创 代码随想录算法训练营第43天 | 1049. 最后一块石头的重量 II 494. 目标和 474.一和零

题目链接:1049.最后一块石头的重量II有一堆石头,每块石头的重量都是正整数。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:如果 x == y,那么两块石头都会被完全粉碎;如果 x!= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。输入:[2,7,4,1,8,1]输出:1。

2024-02-04 10:30:00 697

原创 代码随想录算法训练营第42天 | 01背包问题,你该了解这些! 01背包问题,你该了解这些! 滚动数组 416. 分割等和子集

首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。如图:在看其他情况。状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。

2024-02-03 18:30:36 825

原创 代码随想录算法训练营第41天 |343. 整数拆分 96.不同的二叉搜索树

j的结束条件是 j < i - 1 ,其实 j < i 也是可以的,不过可以节省一步,例如让j = i - 1,的话,其实在 j = 1的时候,这一步就已经拆出来了,重复计算,所以 j < i - 1。首先一定是遍历节点数,从递归公式:dp[i] += dp[j - 1] * dp[i - j]可以看出,节点数为i的状态是依靠 i之前节点数的状态。dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。注意 枚举j的时候,是从1开始的。

2024-01-26 14:00:00 1581

原创 代码随想录算法训练营第39天 | 62.不同路径 63. 不同路径 II

从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。那么很自然,dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。这样就可以保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。机器人每次只能向下或者向右移动一步。

2024-01-26 10:00:00 1149

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

目录理论基础 509. 斐波那契数 💡解题思路💻实现代码70. 爬楼梯 💡解题思路💻实现代码746. 使用最小花费爬楼梯 💡解题思路💻实现代码动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的.对于动态规划问题,我将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!题目链接:509. 斐波那契数斐波那

2024-01-25 16:30:00 887

原创 代码随想录算法训练营第37天 | 738.单调递增的数字 968.监控二叉树 总结

目录738.单调递增的数字 💡解题思路💻实现代码968.监控二叉树 💡解题思路确定遍历顺序如何隔两个节点放一个摄像头💻实现代码总结题目链接:738.单调递增的数字给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)示例 1:示例 2:示例 3:说明: N 是在 [0, 10^9] 范围内的一个整数。题目要求小于等于N的最大单调递增的整数,那么拿一个两

2024-01-25 10:00:00 938

原创 代码随想录算法训练营第36天 |435. 无重叠区间 763.划分字母区间 56. 合并区间

此时问题就是要求非交叉区间的最大个数。这里记录非交叉区间的个数还是有技巧的,如图:区间,1,2,3,4,5,6都按照右边界排好序。当确定区间 1 和 区间2 重叠后,如何确定是否与 区间3 也重贴呢?就是取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的。接下来就是找大于区间1结束位置的区间,是从区间4开始。

2024-01-24 10:00:00 942

原创 代码随想录算法训练营第35天 | 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

排序完的people: [[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]

2024-01-23 10:00:00 975

原创 代码随想录算法训练营第34天 |1005.K次取反后最大化的数组和 134. 加油站 135. 分发糖果

如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。

2024-01-22 16:11:27 897

原创 代码随想录算法训练营第32天 | 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II

如图:i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。如果 cover 大于等于了终点下标,直接 return true 就可以了。

2024-01-18 11:34:14 928

原创 代码随想录算法训练营第31天 | 理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和

相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。在计算是否有峰值的时候,大家知道遍历的下标 i ,计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i]),如果。细心的录友可以发现,这种写法,两个循环的顺序改变了,先遍历的饼干,在遍历的胃口,这是因为遍历顺序变了,我们是从小到大遍历。如果从大到小开始遍历,就for值大的,if值小的。

2024-01-17 21:50:57 896

原创 代码随想录算法训练营第30天 | 332.重新安排行程 51. N皇后 37. 解数独 总结

回溯总结。

2024-01-16 17:38:55 885

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

可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。当收集元素的数组path的大小达到和nums数组一样大的时候,说明找到了一个全排列,也表示到达了叶子节点。本题求子序列,很明显一个元素不能重复使用,所以需要startIndex,调整下一层递归的起始位置。可以不加终止条件,startIndex每次都会加1,并不会无限递归。

2024-01-16 11:25:22 920

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

例如:"0.1.2.201" 和 "192.168.1.1" 是 有效的 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效的 IP 地址。示例: 输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]从图中可以看出,同一树层上重复取2 就要过滤掉,同一树枝上就可以重复取2,因为同一树枝上元素的集合才是唯一子集!

2024-01-15 19:46:10 934

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

在处理组合问题的时候,递归参数需要传入startIndex,表示下一轮递归遍历的起始位置,这个startIndex就是切割线。

2024-01-13 13:27:23 881

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

图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。其实这里sum这个参数也可以省略,每次targetSum减去选取的元素数值,然后判断如果targetSum为0了,说明收集到符合条件的结果了,我这里为了直观便于理解,还是加一个sum参数。如果此时path里收集到的元素和(sum) 和targetSum(就是题目描述的n)相同了,就用result收集当前的结果。

2024-01-12 21:39:40 950

原创 代码随想录算法训练营第24天 | 理论基础 77. 组合

回溯法也可以叫做回溯搜索法,它是一种搜索的方式。

2024-01-12 16:52:44 939

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

关于二叉树,你该了解这些!:二叉树的种类、存储方式、遍历方式、定义方式。

2024-01-11 17:36:53 794 2

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

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回插入后二叉搜索树的根节点。将删除节点(元素7)的左孩子放到删除节点(元素7)的右子树的最左面节点(元素8)的左孩子上,就是把5为根节点的子树移到了8的左孩子的位置。动画中的二叉搜索树中,删除元素7, 那么删除节点(元素7)的左孩子就是5,删除节点(元素7)的右子树的最左面节点是元素8。终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。

2024-01-11 11:43:49 928 1

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

示例 2: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。示例 1: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。

2024-01-09 18:59:12 856 1

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

因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。这表示一个数组大小是1的时候,构造了一个新的节点,并返回。

2024-01-08 20:41:32 933

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

找到。

2024-01-08 15:50:57 985

原创 代码随想录算法训练营第17天 |110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。此时还没完,递归完,要做回溯啊,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点。判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int。递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0。

2024-01-05 16:42:31 956 1

原创 代码随想录算法训练营第16天 | 104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数

那么使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。所以这道题的迭代法就是一道模板题,可以使用二叉树层序遍历的模板来解决的。本题依然是前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

2024-01-04 22:05:35 807 1

原创 代码随想录算法训练营第15天 | 层序遍历10 226.翻转二叉树 101.对称二叉树

这道题目我们也可以使用迭代法,但要注意,这里的迭代法可不是前中后序的迭代写法,因为本题的本质是判断两个树是否是相互翻转的,其实已经不是所谓二叉树遍历的前中后序的关系了。因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

2024-01-03 21:47:55 824 1

空空如也

空空如也

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

TA关注的人

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