- 博客(56)
- 收藏
- 关注
原创 代码随想录算法训练营day60
如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),rigt(6),但是得不到 left。如果数组本身就是升序的,例如[2,4,6,8],那么入栈之后 都是单调递减,一直都没有走 情况三 计算结果的哪一步,所以最后输出的就是0了。之后又将6 加入栈(此时8已经弹出了),然后 就是 4 与 栈口元素 8 进行比较,周而复始,那么计算的最后结果resutl就是0。本题要查找的是右边第一个比元素小的值进行计算,所以使用了递减单调栈(从栈口到栈底)
2023-08-08 21:16:26
298
原创 代码随想录算法训练营day59
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。其实不用,栈里就存放下标就行,想要知道对应的高度,通过height[stack.top()] 就知道弹出的下标对应的高度了。
2023-08-08 13:29:56
340
原创 代码随想录算法训练营day58
题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。在遍历nums2的过程中,我们要判断nums2[i]是否在nums1中出现过,因为最后是要根据nums1元素的下标来更新result数组。
2023-08-06 12:56:05
197
原创 代码随想录算法训练营day57
647. 回文子串 - 力扣(LeetCode)给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。回文字符串 是正着读和倒过来读一样的字符串。子字符串 是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。动规五部曲本题如果我们定义,dp[i] 为 下标i结尾的字符串有 dp[i]个回文串的话,我们会发现很难找到递归关系。dp[i] 和 dp[i-1] ,dp[i + 1] 看上去都没啥关系。所以我们要看回文串的性质。 如图:
2023-08-06 11:25:31
157
原创 代码随想录算法训练营day56
那最后当然是取最小值,所以当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});因为 dp[i][j - 1] + 1 = dp[i - 1][j - 1] + 2,所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
2023-08-05 16:42:33
392
原创 代码随想录算法训练营day55
t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];其实这里 大家可以发现和。
2023-08-05 13:43:55
291
原创 代码随想录算法训练营day51
dp[i][j]:第i天状态为j,所剩的最多现金为dp[i][j]。具体可以区分出如下四个状态:状态一:持有股票状态(今天买入股票,或者是之前就买入了股票然后没有操作,一直持有)不持有股票状态,这里就有两种卖出股票状态。
2023-08-01 21:18:58
213
原创 代码随想录算法训练营day50
一定是选最大的,所以 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] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);那么dp[i][1]究竟选 dp[i-1][0] - prices[i],还是dp[i - 1][1]呢?
2023-08-01 20:23:37
182
原创 代码随想录算法训练营day49
那么第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]);其基础都是要从dp[0][0]和dp[0][1]推导出来。
2023-07-31 20:45:15
380
原创 代码随想录算法训练营day48
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。从dp[i]的定义上来讲,dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历!
2023-07-30 16:57:57
241
原创 代码随想录算法训练营day46
从递推公式中可以看出,dp[i] 的状态依靠 dp[j]是否为true,那么dp[0]就是递推的根基,dp[0]一定要为true,否则递推下去后面都都是false了。如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true。题目中说是拆分为一个或多个在字典中出现的单词,所以这是完全背包。dp[0]初始为true完全就是为了推导公式。
2023-07-30 15:45:06
265
原创 代码随想录算法训练营day45
凑足总额为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了。)使得它们的和等于 n。本题呢,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]
2023-07-29 15:31:56
326
原创 代码随想录算法训练营day44
所有可能的组合为: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1)那么 dp[0] = 1 有没有含义,其实既可以说 凑成总金额0的货币组合数为1,也可以说 凑成总金额0的货币组合数为0,好像都没有毛病。因为递推公式dp[i] += dp[i - nums[j]]的缘故,dp[0]要初始化为1,这样递归其他dp[i]的时候才会有数值基础。dp[j] 就是所有的dp[j - coins[i]](考虑coins[i]的情况)相加。
2023-07-29 14:19:19
131
原创 代码随想录算法训练营day42
那么如果背包容量为target, dp[target]就是装满 背包之后的重量,所以 当 dp[target] == target 的时候,背包就装满了。01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。本题,相当于背包里放入数值,那么物品i的重量是nums[i],其价值也是nums[i]。01背包中,dp[j] 表示: 容量为j的背包,所背的物品价值最大可以为dp[j]。从dp[j]的定义来看,首先dp[0]一定是0。
2023-07-26 20:40:04
190
原创 代码随想录算法训练营day41
确定遍历顺序,先来看看递归公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
2023-07-25 20:56:47
137
原创 代码随想录算法训练营day39
从递归公式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]一定是有数值的。机器人每次只能向下或者向右移动一步。
2023-07-24 20:56:40
933
原创 代码随想录算法训练营day38
509. 斐波那契数 - 力扣(LeetCode)斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 给你n ,请计算 F(n) 。示例 1:示例 2:示例 3:提示:dp[i]的定义为:第i个数的斐波那契数值是dp[i]状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];dp数组如何初始
2023-07-23 12:52:49
24
原创 代码随想录算法训练营day37
从前向后遍历的话,遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]减一,但此时如果strNum[i - 1]减一了,可能又小于strNum[i - 2]。这么说有点抽象,举个例子,数字:332,从前向后遍历的话,那么就把变成了329,此时2又小于了第一位的3了,真正的结果应该是299。给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。题目要求小于等于N的最大单调递增的整数,那么拿一个两位的数字来举例。
2023-07-23 09:53:10
32
原创 代码随想录算法训练营day36
字符串 S 由小写字母组成。即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。所以一样的套路,先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,处理逻辑稍有不同。这几道题都是判断区间重叠,区别就是判断区间重叠后的逻辑,本题是判断区间重贴后要进行区间合并。给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。给出一个区间的集合,请合并所有重叠的区间。
2023-07-23 09:30:40
26
原创 代码随想录算法训练营day35
整个插入过程如下:排序完的people: [[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]
2023-07-19 21:01:54
26
原创 代码随想录算法训练营day34
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。此时局部最优:只要右边评分比左边大,右边的孩子就多一个糖果,全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果。这道题目一定是要确定一边之后,再确定另一边,例如比较每一个孩子的左边,然后再比较右边,这样从局部最优推出了全局最优,即:相邻的孩子中,评分高的孩子获得更多的糖果。
2023-07-18 20:32:47
123
原创 代码随想录算法训练营day32
i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。如果 cover 大于等于了终点下标,直接 return true 就可以了。这道题目关键点在于:不用拘泥于每次究竟跳几步,而是看覆盖范围,覆盖范围内一定是可以跳过来的,不用管是怎么跳的。
2023-07-17 20:32:58
48
原创 代码随想录算法训练营day31
例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。其实并不会,因为还有一个变量 result 一直在更新 最大的连续和,只要有更大的连续和出现,result 就更新了,那么 result 已经把 4 更新了,后面 连续和变成 3,也不会对最后结果有影响。少于两个元素的序列也是摆动序列。
2023-07-16 16:26:09
60
原创 代码随想录算法训练营day30
输入:[[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]] 输出:[“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”] 解释:另一种有效的行程是 [“JFK”,“SFO”,“ATL”,“JFK”,“ATL”,“SFO”]。但是它自然排序更大更靠后。例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前 所有的机场都用三个大写字母表示(机场代码)。
2023-07-15 15:42:19
67
原创 代码随想录算法训练营day29
可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。当收集元素的数组path的大小达到和nums数组一样大的时候,说明找到了一个全排列,也表示到达了叶子节点。给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。
2023-07-14 21:33:23
30
原创 代码随想录算法训练营day28
例如:“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,因为同一树枝上元素的集合才是唯一子集!
2023-07-14 20:13:35
35
原创 代码随想录算法训练营day27
输入:candidates = [2,3,6,7], target = 7 输出:[[2,2,3],[7]] 解释: 2 和 3 可以形成一组候选,2 + 2 + 3 = 7。输入: candidates = [2,5,2,1,2], target = 5, 输出: [ [1,2,2], [5] ]本题递归函数参数还需要startIndex,因为切割过的地方,不能重复切割,和组合问题也是保持一致的。示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“a”,“b”] ]
2023-07-10 21:05:48
54
原创 代码随想录算法训练营day25
例如 k = 2,n = 4的话,就是在集合[1,2,3,4,5,6,7,8,9]中求 k(个数) = 2, n(和) = 4的组合。示例 2: 输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]],无非就是多了一个限制,本题是要找到和为n的k个数的组合,而整个集合已经是固定的了[1,…输入: candidates = [10,1,2,7,6,1,5], target = 8,本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。
2023-07-09 20:13:03
38
原创 代码随想录算法训练营day24
第一次取1,集合变为2,3,4 ,因为k为2,我们只需要再取一个数就可以了,分别取2,3,4,得到集合[1,2] [1,3] [1,4],以此类推。示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]在上面我们提到了,回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。可以看出这棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不再重复取。n 中所有可能的 k 个数的组合。
2023-07-08 16:14:04
22
原创 代码随想录算法训练营day23
https://leetcode.cn/problems/trim-a-binary-search-tree/给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z2hbjeJ6-1688799211915)(https://code-thinking-1253855093.file.
2023-07-08 14:53:50
44
原创 代码随想录算法训练营day22
因为是有序树,所有 如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组 一定是在 [p, q]区间的。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。
2023-07-07 20:58:26
44
原创 代码随想录算法训练营day21
示例 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。例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]左子树和右子树都是二叉搜索树。
2023-07-06 00:59:04
128
1
原创 代码随想录算法训练营day20
因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。这表示一个数组大小是1的时候,构造了一个新的节点,并返回。
2023-07-04 20:47:43
73
原创 代码随想录算法训练营day18
参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。本题要找出树的最后一行的最左边的值。本题还需要类里的两个全局变量,maxLen用来记录最大深度,result记录最大深度最左节点的数值。当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点。第五步:切割后序数组,切成后序左数组和后序右数组。
2023-07-03 00:25:45
82
1
原创 代码随想录算法训练营day17
https://leetcode.cn/problems/balanced-binary-tree/求高度用后序遍历(左右中)求深度用前序遍历(中左右)二叉树的所有路径https://leetcode.cn/problems/binary-tree-paths/给定一个二叉树,返回所有从根节点到叶子节点的路径。说明: 叶子节点是指没有子节点的节点。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fuzTGL8Z-1688087105581)(https://note.yo
2023-06-30 09:07:41
62
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人