- 博客(64)
- 收藏
- 关注
原创 代码随想录算法训练营第六十三天——总结
一刷随想录,有很多题目的思路简直想象不到,跟着卡哥刷题层层递进,由简入难,但是学习是需要永不止步,刷着后面的前面的题目就已经忘了,最难的不是没有思路解决,而是每一天的坚持,希望后面二刷能够让自己对解题思路更加清晰,能够形成自己的解题思路。
2024-09-20 21:12:58
360
原创 代码随想录算法训练营第六十二天 | A * 算法精讲 (A star算法)
如果题目中,给出 多个可能的目标,然后在这多个目标中 选择最近的目标,这种 A * 就不擅长了, A * 只擅长给出明确的目标 然后找到最短路径。大家看上述 A * 代码的时候,可以看到 我们想 队列里添加了很多节点,但真正从队列里取出来的 仅仅是 靠启发式函数判断 距离终点最近的节点。我们来看一下广搜的搜索过程,如图,红色是起点,绿色是终点,黄色是要遍历的点,最后从 起点 找到 达到终点的最短路径是棕色。如果 使用A * 的话,其搜索过程是这样的,如图,图中着色的都是我们要遍历的点。
2024-09-18 13:31:58
1096
原创 代码随想录算法训练营第六十二天 | Floyd 算法精讲
因为 k 放在最里面,先就把 节点1 和 节点 2 的最短距离就确定了,后面再也不会计算节点 1 和 节点 2的距离,同时也不会基于 初始化或者之前计算过的结果来计算,即:不会考虑 节点1 到 节点3, 节点3 到节点 4,节点4到节点2 的距离。也就是 计算 grid[1][3][2] (表示节点1 到 节点3,经过节点2) 的时候,需要基于 grid[1][2][1] 和 grid[2][3][1]的数值,而 我们初始化,只初始化了 k为0 的那一层。每条道路上行走的距离都是已知的。
2024-09-18 13:24:17
1148
原创 代码随想录算法训练营第六十天 | Bellman_ford之单源有限最短路
所有边进行的第二次松弛,minDist数组为 : -2 -2 -1 0 所有边进行的第三次松弛,minDist数组为 : -3 -3 -2 -1 所有边进行的第四次松弛,minDist数组为 : -4 -4 -3 -2 (本示例中k为3,所以松弛4次)最后计算的结果minDist[4] = -2,即 起点到 节点4,最多经过 3 个节点的最短距离是 -2,但 正确的结果应该是 1,即路径:节点1 -> 节点2 -> 节点3 -> 节点4。理论上来说节点3 应该在对所有边第二次松弛的时候才更新。
2024-09-17 02:13:29
1134
原创 代码随想录算法训练营第六十天 | Bellman_ford之判断负权回路
在 bellman_ford 算法中,松弛 n-1 次所有的边 就可以求得 起点到任何节点的最短路径,松弛 n 次以上,minDist数组(记录起到到其他节点的最短距离)中的结果也不会有改变 (如果对 bellman_ford 算法 不了解,也不知道 minDist 是什么,建议详看上篇讲解。节点1 -> 节点2 -> 节点3 -> 节点1 -> 节点2 -> 节点3 -> 节点4,这样的路径总成本 (-1) + 1 + (-1) + (-1) + 1 + (-1) + 1 = -1。
2024-09-17 01:50:40
1056
原创 代码随想录算法训练营第六十天 | Bellman_ford 队列优化算法
边:节点2 -> 节点4,权值为1 ,minDist[4] > minDist[2] + (-3) ,更新 minDist[4] = minDist[2] + (-3) = 1 + (-3) = -2。边:节点1 -> 节点2,权值为1 ,minDist[2] > minDist[1] + 1 ,更新 minDist[2] = minDist[1] + 1 = 0 + 1 = 1。本图中,对所有边进行松弛,真正有效的松弛,只有松弛 边(节点1->节点2) 和 边(节点1->节点3)。
2024-09-17 01:37:02
1113
原创 代码随想录算法训练营第五十九天 | Bellman_ford 算法精讲
这里要给大家模拟一遍 Bellman_ford 的算法才行,接下来我们来看看对所有边松弛 n - 1 次的操作是什么样的。我们依然使用。
2024-09-15 00:57:47
2046
原创 代码随想录算法训练营第五十九天 | dijkstra(堆优化版)精讲
有了小顶堆自动对边的权值排序,那我们只需要直接从 堆里取堆顶元素(小顶堆中,最小的权值在上面),就可以取到离源点最近的节点了 (未访问过的节点,不会加到堆里进行排序)我们要选择距离源点近的节点(即:该边的权值最小),所以 我们需要一个 小顶堆 来帮我们对边的权值排序,每次从小顶堆堆顶 取边就是权值最小的边。如下图所示,起始车站为 1 号车站,终点车站为 7 号车站,绿色路线为最短的路线,路线总长度为 12,则输出 12。第三步(更新非访问节点到源点的距离),这里的思路 也是 和朴素dijkstra一样的。
2024-09-15 00:53:28
930
原创 代码随想录算法训练营第五十八天 | dijkstra(朴素版)精讲
因为 minDist表示 节点到源点的最小距离,所以 新节点 cur 的加入,需要使用 源点到cur的距离 (minDist[cur]) + cur 到 节点 v 的距离 (grid[cur][v]),才是 源点到节点v的距离。因为 minDist表示 节点到最小生成树的最小距离,所以 新节点cur的加入,只需要 使用 grid[cur][j] ,grid[cur][j] 就表示 cur 加入生成树后,生成树到 节点j 的距离。那么访问过的节点还能继续访问会不会有死循环的出现呢?控制逻辑不让其死循环?
2024-09-14 00:35:29
709
原创 代码随想录算法训练营第五十八天 | 拓扑排序精讲-软件构建
某个大型软件项目的构建系统拥有 N 个文件,文件编号从 0 到 N - 1,在这些文件中,某些文件依赖于其他文件的内容,这意味着如果文件 A 依赖于文件 B,则必须在处理文件 A 之前处理文件 B (0
2024-09-14 00:24:53
1040
原创 代码随想录算法训练营第五十七天 | 53. 寻宝-kruskal算法
排序后的边顺序为[(1,2) (4,5) (1,3) (2,6) (3,4) (6,7) (5,7) (1,5) (3,2) (2,4) (5,6)]选边(1,2),节点1 和 节点2 不在同一个集合,所以生成树可以添加边(1,2),并将 节点1,节点2 放在同一个集合。选边(1,3),节点1 和 节点3 不在同一个集合,生成树添加边(1,3),并将节点1,节点3 放到同一个集合。选边(2,6),节点2 和 节点6 不在同一个集合,生成树添加边(2,6),并将节点2,节点6 放到同一个集合。
2024-09-13 01:52:23
1032
原创 代码随想录算法训练营第五十七天 | 53. 寻宝-prim算法
如果是二维数组,来记录两个点链接,例如 parent[节点编号A][节点编号B] = 1 ,parent[节点编号B][节点编号A] = 1,来表示 节点A 与 节点B 相连,那就没有上面说的这个注意事项了,当然这么做的话,就是多开辟的内存空间。选取一个距离 最小生成树(节点1) 最近的非生成树里的节点,节点2,3,5 距离 最小生成树(节点1) 最近,选节点 2(其实选 节点3或者节点2都可以,距离一样的)加入最小生成树。parent[节点编号] = 节点编号, 这样就把一条边记录下来了。
2024-09-13 01:37:44
1140
原创 代码随想录算法训练营第五十六天 | 108.冗余连接,109.冗余连接II
,这说明在两条边都可以删除的情况下,要删顺序靠后的边!我们来想一下 有向树的性质,如果是有向树的话,只有根节点入度为0,其他节点入度都为1(因为该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点)。所以情况一:如果我们找到入度为2的点,那么删一条指向该节点的边就行了。如图:找到了节点3 的入度为2,删 1 -> 3 或者 2 -> 3。选择删顺序靠后便可。但 入度为2 还有一种情况,情况二,只能删特定的一条边,如图:
2024-09-12 23:12:08
767
原创 代码随想录算法训练营第五十五天 | 寻找存在的路径
为什么说这道题目是并查集基础题目,题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。输出一个整数,代表是否存在从节点 source 到节点 destination 的路径。后续 M 行,每行两个正整数 s 和 t,代表从节点 s 与节点 t 之间有一条边。给定一个包含 n 个节点的无向图中,节点编号从 1 到 n (含 1 和 n )。第一行包含两个正整数 N 和 M,N 代表节点的个数,M 代表边的个数。以上模板中,只要修改 n 大小就可以。
2024-09-11 11:57:02
295
原创 代码随想录算法训练营第五十三天 | 110.字符串接龙 ,105.有向图的完全可达性 ,106.岛屿的周长
如果我们是处理当前访问的节点,当前访问的节点如果是 true ,说明是访问过的节点,那就终止本层递归,如果不是true,我们就把它赋值为true,因为这是我们处理本层递归的节点。给定一个有向图,包含 N 个节点,节点编号分别为 1,2,...,N。此时就要在思考本题的要求了,本题是需要判断 1节点 是否能到所有节点,那么我们就没有必要回溯去撤销操作了,只要遍历过的节点一律都标记上。当我们需要搜索一条可行路径的时候,就需要回溯操作了,因为没有回溯,就没法“调头”, 如果不理解的话,去看我写的。
2024-09-11 02:47:52
727
原创 代码随想录算法训练营第五十二天 | 101.孤岛的总面积,102.沉没孤岛 ,103.水流问题 ,104.建造最大岛屿
第二步:再遍历地图,遍历0的方格(因为要将0变成1),并统计该1(由0变成的1)周边岛屿面积,将其相邻面积相加在一起,遍历所有 0 之后,就可以得出 选一个0变成1 之后的最大面积。思路依然是从地图周边出发,将周边空格相邻的陆地都做上标记,然后在遍历一遍地图,遇到 陆地 且没做过标记的,那么都是地图中间的 陆地 ,全部改成水域就行。岛屿面积的计算方式为组成岛屿的陆地的总数。给定一个由 1(陆地)和 0(水)组成的矩阵,你最多可以将矩阵中的一格水变为一块陆地,在执行了此操作之后,矩阵中最大的岛屿面积是多少。
2024-09-10 23:51:45
1206
原创 代码随想录算法训练营第五十一天 | 99.岛屿数量-深搜 ,99.岛屿数量-广搜 ,100.岛屿的最大面积
很多同学写dfs其实也是凭感觉来的,有的时候dfs函数中写终止条件才能过,有的时候 dfs函数不写终止添加也能过!本题思路,是用遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。写法一,dfs只处理下一个节点,即在主函数遇到岛屿就计数为1,dfs处理接下来的相邻陆地。其实终止条件 就写在了 调用dfs的地方,如果遇到不合法的方向,直接不会去调用dfs。写法二,dfs处理当前节点,即在主函数遇到岛屿就计数为0,dfs处理接下来的全部陆地。输出一个整数,表示岛屿的最大面积。
2024-09-07 00:52:15
1083
原创 代码随想录算法训练营第五十天 | 98. 所有可达路径
本题我们会有n 个节点,因为节点标号是从1开始的,为了节点标号和下标对齐,我们申请 n + 1 * n + 1 这么大的二维数组。有五个节点,其中的从 1 到达 5 的路径有两个,分别是 1 -> 3 -> 5 和 1 -> 2 -> 4 -> 5。输出所有的可达路径,路径中所有节点的后面跟一个空格,每条路径独占一行,存在多条路径,路径输出的顺序可任意。邻接矩阵是从节点的角度来表示图,有多少节点就申请多大的二维数组。首先我们dfs函数一定要存一个图,用来遍历的,需要存一个目前我们遍历的节点,定义为x。
2024-09-05 02:13:03
1068
原创 代码随想录算法训练营第四十九天 |84.柱状图中最大的矩形
随后我们从这跟柱子开始向两侧延伸,直到遇到高度小于 h 的柱子,就确定了矩形的左右边界。如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),rigt(6),但是得不到 left。如果数组本身就是升序的,例如[2,4,6,8],那么入栈之后 都是单调递减,一直都没有走 情况三 计算结果的哪一步,所以最后输出的就是0了。那么因为本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!
2024-09-04 23:19:09
1102
原创 代码随想录算法训练营第四十九天 | 42. 接雨水
本题暴力解法也是也是使用双指针。首先要明确,要按照行来计算,还是按照列来计算。按照行来计算如图: 按照列来计算如图: 一些同学在实现的时候,很容易一会按照行来计算一会按照列来计算,这样就会越写越乱。我个人倾向于按照列来计算,比较容易理解,接下来看一下按照列如何计算。首先,如果按照列来计算的话,宽度一定是1了,我们再把每一列的雨水的高度求出来就可以了。可以看出每一列雨水的高度,取决于,该列 左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度。这句话可以有点绕,来举一个理解,例如求列4的雨水高度,如图:列4
2024-09-04 11:50:18
1232
原创 代码随想录算法训练营第四十八天 | 739. 每日温度, 496.下一个更大元素 I ,503.下一个更大元素II
题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。在遍历nums2的过程中,我们要判断nums2[i]是否在nums1中出现过,因为最后是要根据nums1元素的下标来更新result数组。
2024-09-04 01:13:37
1054
原创 代码随想录算法训练营第四十六天 | 647. 回文子串 ,516.最长回文子序列
目录647. 回文子串思路暴力解法动态规划1.确定dp数组(dp table)以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组方法一: 动态规划方法二:动态规划-简洁方法三:双指针法516.最长回文子序列 思路1.确定dp数组(dp table)以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组方法一:动态规划两层for循环,遍历区间起始位置和终止位置,然后还需要一层遍历判断这个区间是不是回文。所以时间复杂度:O(n^3)动规五部
2024-09-03 03:08:14
1075
原创 代码随想录算法训练营第四十五天 | 115.不同的子序列 ,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});因为 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);
2024-09-03 01:04:45
1019
原创 代码随想录算法训练营第四十四天 | 1143.最长公共子序列 , 1035.不相交的线 , 53. 最大子序和 ,392.判断子序列
而是dp[6]。在回顾一下dp[i]的定义:包括下标i之前的最大连续子序列和为dp[i]。那么我们要找最大的连续子序列,就应该找每一个i为终点的连续最大子序列。所以在递推公式的时候,可以直接选出最大的dp[i]。
2024-09-01 16:44:07
1071
原创 代码随想录算法训练营第四十三天 | 300.最长递增子序列 , 674. 最长连续递增序列 , 718. 最长重复子数组
本题中,正确定义dp数组的含义十分重要。dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度为什么一定表示 “以nums[i]结尾的最长递增子序” ,因为我们在 做 递增比较的时候,如果比较 nums[j] 和 nums[i] 的大小,那么两个递增子序列一定分别以nums[j]为结尾 和 nums[i]为结尾, 要不然这个比较就没有意义了,不是尾部元素的比较那么 如何算递增呢。
2024-08-28 23:54:37
1145
原创 代码随想录算法训练营第四十二天 | 188.买卖股票的最佳时机IV ,309.最佳买卖股票时机含冷冻期 ,714.买卖股票的最佳时机含手续费
给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例 1:输入:k = 2, prices = [2,4,1]输出:2 解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2。
2024-08-28 20:18:36
1190
原创 代码随想录算法训练营第四十一天 | 121. 买卖股票的最佳时机 , 122.买卖股票的最佳时机II , 123.买卖股票的最佳时机III
所以dp[4][4]已经包含了dp[4][2]的情况。那么第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][1] ,并不是说 第i天一定买入股票,有可能 第 i-1天 就买入了,那么 dp[i][1] 延续买入股票的这个状态。
2024-08-28 01:17:29
1184
原创 代码随想录算法训练营第三十九天 | 198.打家劫舍 , 213.打家劫舍II , 337.打家劫舍III
目录198.打家劫舍思路1.确定dp数组(dp table)以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组方法一: 动态规划-一维方法二:动态规划-二维方法三:动态规划-两个变量213.打家劫舍II思路方法一:动态规划-方法二:动态规划-二维方法三:动态规划-不封装函数 337.打家劫舍III 思路暴力递归记忆化递推动态规划1.确定递归函数的参数和返回值2.确定终止条件3.确定遍历顺序4.确定单层递归的逻辑5.举例推导dp数组方法一:暴力递归方法二:记忆化递归方法三
2024-08-27 12:06:05
1118
原创 代码随想录算法训练营第三十八天 | 322. 零钱兑换 ,279.完全平方数 ,139.单词拆分
凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j](考虑coins[i])从递推公式中可以看出,dp[i] 的状态依靠 dp[j]是否为true,那么dp[0]就是递推的根基,dp[0]一定要为true,否则递推下去后面都都是false了。换句话说,其值等于一个整数自乘的积。dp[j] 可以由dp[j - i * i]推出, dp[j - i * i] + 1 便可以凑成dp[j]。
2024-08-27 01:20:36
1055
原创 代码随想录算法训练营第三十七天 | 518. 零钱兑换 II , 377. 组合总和 Ⅳ,70. 爬楼梯 (进阶)
dp[0]=1还说明了一种情况:如果正好选了coins[i]后,也就是j-coins[i] == 0的情况表示这个硬币刚好能选,此时dp[0]为1表示只选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]而不会出现{5, 1}的情况。
2024-08-26 10:11:23
1278
原创 代码随想录算法训练营第三十六天 | 1049. 最后一块石头的重量 II , 494. 目标和 , 474.一和零
力扣题目链接代码随想录这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II有一堆石头,每块石头的重量都是正整数。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:如果 x == y,那么两块石头都会被完全粉碎;如果 x!= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。
2024-08-25 19:20:53
1227
原创 代码随想录算法训练营第三十五天 | 416. 分割等和子集
那么如果背包容量为target, dp[target]就是装满 背包之后的重量,所以 当 dp[target] == target 的时候,背包就装满了。01背包的递推公式为:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);而dp[6] 就可以等于6了,放进1 和 5,那么dp[6] == 6,说明背包装满了。01背包中,dp[j] 表示: 容量为j的背包,所背的物品价值最大可以为dp[j]。从dp[j]的定义来看,首先dp[0]一定是0。
2024-08-24 02:30:40
979
原创 代码随想录算法训练营第三十四天 | 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-08-22 16:46:44
898
原创 代码随想录算法训练营第三十二天 | 509. 斐波那契数 , 70. 爬楼梯 , 746. 使用最小花费爬楼梯
目录509. 斐波那契数思路1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组方法一: 动态规划1方法二:动态规划2方法三:动态规划3方法四:递归 70. 爬楼梯思路1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组方法一:动态规划1方法二:动态规划2方法三:动态规划3746. 使用最小花费爬楼梯 思路1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp
2024-08-22 03:18:44
967
原创 代码随想录算法训练营第三十一天 | 56. 合并区间 , 738.单调递增的数字 , 968.监控二叉树
本题目中count计算摄像头的数目,不能定义为count = 0,因为int属于不可变类型,在递归中,每一层的count都不会相互影响,所以最终返回值永远都是0,而数组属于可变类型,在每一层的递归中,指向的都是同一个地址,所以修改count会影响所有。那么空节点不能是无覆盖的状态,这样叶子节点就要放摄像头了,空节点也不能是有摄像头的状态,这样叶子节点的父节点就没有必要放摄像头了,而是可以把摄像头放在叶子节点的爷爷节点上。那么递归的终止条件应该是遇到了空节点,此时应该返回2(有覆盖),原因上面已经解释过了。
2024-08-21 23:47:39
784
原创 代码随想录算法训练营第三十天 | 452. 用最少数量的箭引爆气球,435. 无重叠区间, 763.划分字母区间
此时问题就是要求非交叉区间的最大个数。这里记录非交叉区间的个数还是有技巧的,如图:区间,1,2,3,4,5,6都按照右边界排好序。当确定区间 1 和 区间2 重叠后,如何确定是否与 区间3 也重贴呢?就是取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的。接下来就是找大于区间1结束位置的区间,是从区间4开始。
2024-08-21 00:07:16
751
原创 代码随想录算法训练营第二十九天 | 134. 加油站 , 135. 分发糖果 ,860.柠檬水找零, 406.根据身高重建队列
局部最优可推出全局最优,找不出反例,那就试试贪心。一些同学可能也会疑惑,你怎么知道局部最优就可以推出全局最优呢?有数学证明么?在贪心系列开篇词。
2024-08-14 22:18:28
1035
原创 代码随想录算法训练营第二十八天 | 122.买卖股票的最佳时机II , 55. 跳跃游戏 , 45.跳跃游戏II , 1005.K次取反后最大化的数组和
局部最优推出全局最优,找不出反例,试试贪心!如图:i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。如果 cover 大于等于了终点下标,直接 return true 就可以了。
2024-08-13 23:27:52
2082
原创 代码随想录算法训练营第二十七天 | 455.分发饼干,376. 摆动序列 ,53. 最大子序和
其实并不会,因为还有一个变量 result 一直在更新 最大的连续和,只要有更大的连续和出现,result 就更新了,那么 result 已经把 4 更新了,后面 连续和变成 3,也不会对最后结果有影响。在计算是否有峰值的时候,大家知道遍历的下标 i ,计算 prediff=nums[i] - nums[i-1] 和 curdiff=nums[i+1] - nums[i],如果。注意版本一的代码中,可以看出来,是先遍历的胃口,在遍历的饼干,那么可不可以 先遍历 饼干,在遍历胃口呢?
2024-08-13 00:55:24
1234
原创 代码随想录算法训练营第二十五天 | 491.递增子序列 ,46.全排列 ,47.全排列 II
可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。大家应该很清晰的看到,树层上对前一位去重非常彻底,效率很高,树枝上对前一位去重虽然最后可以得到答案,但是做了很多无用搜索。因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。本题给出的示例,还是一个有序数组 [4, 6, 7, 7],这更容易误导大家按照排序的思路去做了。而且本题也要求不能有相同的递增子序列。
2024-08-11 00:23:44
1140
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人