- 博客(59)
- 收藏
- 关注
原创 动态规划机试2023.4.19
ex12.1 吃糖果和(eg12.1的程序一模一样)eg12.5 最大上升子序列和(北京大学复试上机题)ex12.2 最大连续子序列(浙江大学复试上机题)eg12.3 最大子矩阵(北京大学复试上机题)eg12.4 拦截导弹(北京大学复试上机题)ex12.3 合唱队形(北京大学复试上机题)复习了二维前缀和并且使用暴力做法解出该题。eg12.1 N阶楼梯上楼问题。eg12.2 最大序列和。
2023-04-19 20:36:36
344
原创 图论2023.4.14
分析:不仅需要判断所有点是否属于一个集合,还需要判断各个点是否符合树的定义,而判断各点是否符合树的定义可以转换为判断它的入度是否符合要求,根结点的入度为0,而其余点的入度为1.只要各个结点满足入度要求,只有一个根节点,以及各个结点属于同一集合,就可以构成一棵树。但是在合并中,为了避免因为树的退化而产生额外的时间消耗,可以在查找某特定结点的根结点的同时,将其与根结点之间的所有结点都直接指向根结点。(北京大学复试上机题)ex11.5 继续畅通工程(浙江大学复试上机题)ex1.畅通工程(浙江大学复试上机题)
2023-04-18 18:36:56
553
原创 KMP算法
算法思想:从S的第一个字符起,与模式T的第一个字符比较,若相等,则继续逐个比较后续字符;以此类推,直至模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则匹配成功。给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。串中的任意多个连续的字符组成的子序列称为该串的子串,包含子串的串称为主串。子串的定位操作通常称为串的模式匹配,它求的是子串(模式串)在主串中的位置。串中字符的个数n称为串的长度。
2023-04-10 20:20:03
502
原创 代码随想录一刷总结
上数据结构的课程的时候,虽然懂得了dfs/回溯的基本原理,但是对其实现一直是处于一个一知半解的状态,通过代码随想录的学习,我真正地了解了回溯算法的本质,及其解题步骤。数据结构中链表是在专门的一章中进行讲解的,所以比较熟悉,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。首先,数组是存放在连续内存空间上的相同类型数据的集合,其次数组的下标都是从0开始的,数组内存空间的地址都是连续的。
2023-04-02 15:30:24
620
原创 代码随想录算法训练营第六十天|84.柱状图中最大的矩形
为什么这么说呢,接雨水那道题目找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。那么因为本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!只有栈里从大到小的顺序,才能保证栈顶元素找到左右两边第一个小于栈顶元素的柱子。单调栈从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。求在该柱状图中,能够勾勒出来的矩形的最大面积。本地单调栈的解法和接雨水的题目是遥相呼应的。此时大家应该可以发现其实就是。
2023-04-01 13:24:00
872
原创 代码随想录算法训练营第五十九天|503.下一个最大元素Ⅱ、42.接雨水
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。其实不用,栈里就存放下标就行,想要知道对应的高度,通过height[stack.top()] 就知道弹出的下标对应的高度了。
2023-03-31 12:23:50
240
原创 代码随想录算法训练营第五十八天|739.每日温度、496.下一个更大元素Ⅰ
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。
2023-03-30 10:13:25
222
原创 代码随想录算法训练营第五十七天|647.回文子串、516.最长回文子序列
其他情况dp[i][j]初始为0就行,这样递推公式:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);中dp[i][j]才不会被初始值覆盖。如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
2023-03-29 10:05:17
198
原创 代码随想录算法训练营第五十六天|583.两个字符串的删除操作、72.编辑距离
一、两个字符串的删除操作给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。分析如下:这次是两个字符串可以相互删了,这种题目也知道用动态规划的思路来解,动规五部曲,分析如下:1.确定dp数组(dp table)以及下标的含义dp[i][j]:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。这里dp数组的定义有点点绕,大家要撸清思路。
2023-03-28 09:55:23
553
原创 代码随想录算法训练营第五十五天|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];if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;从递推公式可以看出dp[i][j]都是依赖于dp[i - 1][j - 1] 和 dp[i][j - 1],所以dp[0][0]和dp[i][0]是一定要初始化的。
2023-03-27 07:46:58
233
原创 代码随想录算法训练营第五十三天|1143.最长公共子序列、1035.不相交的线、53.最大子序和 动态规划
例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。现在,我们可以绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且我们绘制的直线不与任何其他连线(非水平线)相交。一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。
2023-03-25 09:50:53
353
原创 代码随想录算法训练营第五十二天|300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组
连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。但dp[i][0] 和dp[0][j]要初始值,因为 为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;
2023-03-24 15:09:50
202
原创 代码随想录算法训练营第五十一天|309.最佳股票买卖时机含冷冻期、714.最佳股票买卖时机含手续费
如果i为1,第1天买入股票,那么递归公式中需要计算 dp[i - 1][1] - prices[i] ,即 dp[0][1] - prices[1],那么大家感受一下 dp[0][1] (即第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]。
2023-03-23 07:57:43
121
原创 代码随想录算法训练营第五十天|123.买卖股票的最佳时机Ⅲ、188.买卖股票的最佳时机Ⅳ
一定是选最大的,所以 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][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])那么dp[i][1]究竟选 dp[i-1][0] - prices[i],还是dp[i - 1][1]呢?此时还没有买入,怎么就卖出呢?
2023-03-22 10:00:59
87
原创 代码随想录算法训练营第四十九天|121.买卖股票的最佳时机、122买卖股票的最佳时机Ⅱ
由递推公式 dp[i][0] = max(dp[i - 1][0], -prices[i]);和 dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);同样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]);
2023-03-20 22:49:18
407
原创 代码随想录算法训练营第四十八天|198.打家劫舍、213.打家劫舍Ⅱ、337.打家劫舍Ⅲ
如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。从dp[i]的定义上来讲,dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);然后dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
2023-03-19 22:54:54
259
原创 代码随想录算法训练营第四十六天|139.单词拆分、多重背包、背包问题总结篇
一·、单词划分给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。分析如下:动规五部曲分析如下:1.确定dp数组以及下标的含义。2.确定递推公式如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i )。所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true。3.dp数组如何初始化。
2023-03-17 23:10:33
584
原创 代码随想录算法训练营第四十五天|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]所以遍历的内循环是正序。
2023-03-17 15:41:11
381
原创 代码随想录算法训练营第四十四天|完全背包、518.零钱兑换Ⅱ、377.组合总和Ⅳ
dp[0]=1还说明了一种情况:如果正好选了coins[i]后,也就是j-coins[i] == 0的情况表示这个硬币刚好能选,此时dp[0]为1表示只选coins[i]存在这样的一种选法。因为递推公式dp[i] += dp[i - nums[j]]的缘故,dp[0]要初始化为1,这样递归其他dp[i]的时候才会有数值基础。下标非0的dp[j]初始化为0,这样累计加dp[j - coins[i]]的时候才不会影响真正的dp[j]初始化为0,这样才不会影响dp[i]累加所有的dp[i - nums[j]]。
2023-03-16 07:57:59
343
原创 代码随想录算法训练营第四十三天|1049.最后一块石头的重量Ⅱ、494.目标和、474.一和零
接下来就是如何初始化dp[j]呢,因为重量都不会是负数,所以dp[j]都初始化为0就可以了,这样在递归公式dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);其实也可以使用二维dp数组来求解本题,dp[i][j]:使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
2023-03-15 10:11:19
89
原创 代码随想录算法训练营第四十一天|343.整数划分、96.不同的二叉搜索树
从递归公式上来讲,dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 中以j为头结点左子树节点数量为0,也需要dp[以j为头结点左子树节点数量] = 1, 否则乘法的结果就都变成0了。首先一定是遍历节点数,从递归公式:dp[i] += dp[j - 1] * dp[i - j]可以看出,节点数为i的状态是依靠 i之前节点数的状态。dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。返回你可以获得的最大乘积。
2023-03-13 08:01:41
88
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人