精选
文章平均质量分 65
精选
hlc@
这个作者很懒,什么都没留下…
展开
-
【划分型DP】力扣2830. 销售利润最大化
我们可以以某个offer的end为索引储存到数组group中,储存的是start和gold数据,也就是offer[0]和offer[2]。将位于 [0,0] 范围内的房屋以 1 金币的价格出售给第 1 位买家,并将位于 [1,3] 范围内的房屋以 2 金币的价格出售给第 3 位买家。输入:n = 5, offers = [[0,0,1],[0,2,10],[1,3,2]]输入:n = 5, offers = [[0,0,1],[0,2,2],[1,3,2]]返回你可以赚取的金币的最大数目。原创 2024-11-26 17:58:58 · 239 阅读 · 0 评论 -
【数据结构-队列】力扣1670. 设计前中后队列
从 [1, 2, 3, 4, 5, 6] 的中间位置弹出元素,返回 3 ,数组变为 [1, 2, 4, 5, 6]。int popMiddle() 将 正中间 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1。将 6 添加到 [1, 2, 3, 4, 5] 的中间位置,结果数组为 [1, 2, 6, 3, 4, 5]。int popFront() 将 最前面 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1。// 返回 1 -> [4, 3, 2]原创 2024-11-25 20:54:55 · 169 阅读 · 0 评论 -
【数据结构-队列】力扣232. 用栈实现队列
而在这一题栈模拟队列中,如果使用那种做法会发现我们没办法将栈元素的排列顺序和队列类似,所以我们就只需要按栈的顺序来排列元素,然后我们在pop的时候,将栈底的元素弹出就行。那么要将栈底的元素弹出,我们就需要另外一个栈st2来辅助,我们将栈st1的元素全部推入st2中,然后st1的栈底元素就在st2的栈顶,将st2栈顶的元素pop并返回后,再将st2的元素推入st1中,这时候就可以实现st1栈底元素被pop掉。假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)原创 2024-11-23 14:51:21 · 440 阅读 · 0 评论 -
【数据结构-队列】力扣225. 用队列实现栈
栈是后进先出,队列是先进先出,所以我们需要做的就是将最后进入的元素能够放在队列的前面,由于队列是从后面推入元素,所以我们就将要推入的元素先放到队列q2中,然后再将q1的元素推入到q2,这时候要推入的元素就在队列的最前面,如果pop的话就会先pop出最后进入的元素。然后我们swap队列q1和q2,这样才能够不断循环,以队列q1为主要模拟栈,队列q2是用来辅助的。请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。// 返回 False。原创 2024-11-23 14:08:46 · 288 阅读 · 0 评论 -
【数据结构-表达式解析】力扣227. 基本计算器 II
那么当我们遍历3的时候,会被储存在num中,当遇到加号的时候,就会将num给push到栈中,然后将preSign更新为加号,然后遍历到5,记录到num中,然后空格跳过,接下来遇到除号,我们这时候不进行除号运算,而是进行前面preSign的运算,preSign是加号,也就是继续将5推入栈中,运算完后将preSign更新为除号,然后遍历2,记录num=2,这时候经过while循环的i++,此时i=n,触发了if判断,此时preSign为除号,将栈顶的5除以当前的num值2。输入:s = " 3/2 "原创 2024-11-20 19:53:33 · 513 阅读 · 0 评论 -
【数据结构-表达式解析】【hard】力扣224. 基本计算器
所以我们可以构建一个栈st来储存符号,我们初始化符号sign(1或-1)为1,当我们遍历字符串的时候,遇到左括号,就往栈中推入sign,推入的sign会位于栈顶,作用于这个左括号开始到右括号结束之间的符号,假设我们这时候sign是-1,然后遇到了一个左括号,然后接着在这个括号范围内遇到了一个减号,那么他就将sign变为1,也就是我们所说的负负得正,接着当我们遇到右括号的时候,就弹出栈顶的sign,因为栈顶的sign只作用于这个括号范围。输入:s = “(1+(4+5+2)-3)+(6+8)”原创 2024-11-20 17:36:32 · 393 阅读 · 0 评论 -
【划分型 DP-约束划分个数】【hard】【阿里笔试】力扣1278. 分割回文串 III
想象我们有一个指针m,他的作用是在m处作为状态转移的位置,于是我们可以由f[m][j-1]也就是从m-1下标开始及之前分割成j-1个回文串需要的最少修改字符数,然后加上cost[m][i-1]也就是f[i][j]。然后我们定义一个二维数组f[i][j],用 f[i][j] 表示对于字符串 S 的前 i 个字符,将它分割成 j 个非空且不相交的回文串,最少需要修改的字符数。我们遍历数组,然后内层循环j,当j=1的时候,说明不分割,所以f[i][1] = cost[0][i-1]。s 中只含有小写英文字母。原创 2024-11-19 13:48:43 · 770 阅读 · 0 评论 -
【划分型DP-约束划分个数】力扣813. 最大平均值和的分组
因为由于我们状态进行了压缩,所以f[x]里面实际上保存的信息是上一轮的数据,如果我们i使用正序去遍历,那么f[i]就会覆盖掉f[x]的数据,导致在状态转移的过程中,无法读取到上一轮的f[x]的数据。,也就是说,我们枚举i后,从j-1到i-1的范围内枚举x,这样子f[i][j]就可以由f[x][j-1]加上第x个元素到第i个元素的平均值转移而来。nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20.输出: 20.00000。原创 2024-11-18 23:04:37 · 455 阅读 · 0 评论 -
【划分型DP-约束划分个数】【hard】力扣1745. 分割回文串 IV
我们预处理完字符串后,我们可以观察题目是是否能分割成三个非空回文子字符串,所以我们只需要枚举中间的范围,然后从开头0到i-1就是第一个范围,从j+1到n-1就是第三个范围。给你一个字符串 s ,如果可以将它分割成三个 非空 回文子字符串,那么返回 true ,否则返回 false。首先要做的是预处理,看字符串中哪些范围是回文串,然后我们将它记录到数组f中。解释:“abcbdd” = “a” + “bcb” + “dd”,三个子字符串都是回文的。如果遍历完后还没有返回true,那么就返回false。原创 2024-11-18 01:00:41 · 790 阅读 · 0 评论 -
【划分型DP-约束划分个数】力扣1043. 分隔数组以得到最大和
我们在推到f[i]的时候,我们可以从i开始枚举j,来枚举分割的区间,然后我们可以通过。倒序遍历 j 的过程中可以顺便维护区间最大值,这样 d[i] 的转移可以在 O(k) 的时间内完成。来求出[j,i]的最大和是多少,因为这时候j小于i,所以我们也知道f[j]是多少,这时候我们可以状态转移。输入:arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4。输入:arr = [1,15,7,9,2,5,10], k = 3。解释:数组变为 [15,15,15,9,10,10,10]原创 2024-11-16 22:45:03 · 219 阅读 · 0 评论 -
【划分型DP-约束划分个数】【hard】力扣410. 分割数组的最大值
这道题的目的就是要找出连续子数组的最大值,那么我们可以思考,我们是不是可以假设一个最大值,然后看一下如果要让子数组分割的最大值不超过假定的最大值,那么要分割几次。一旦分割的次数小于等于题目要求的k的话,那么就说明假定的最大值大于等于实际的最大值,那么就让right = mid,这样才可以让接下来假定的最大值变小。给定一个非负整数数组 nums 和一个整数 k ,你需要将这个数组分成 k 个非空的连续子数组,使得这 k 个子数组各自和的最大值 最小。输入:nums = [1,2,3,4,5], k = 2。原创 2024-11-13 22:27:06 · 354 阅读 · 0 评论 -
【划分型DP-最优划分】【hard】力扣639. 解码方法 II
解释:这一条编码消息可以表示 “11”、“12”、“13”、“14”、“15”、“16”、“17”、“18” 或 “19” 中的任意一条。解释:这一条编码消息可以表示 “21”、“22”、“23”、“24”、“25”、“26”、“27”、“28” 或 “29” 中的任意一条。解释:这一条编码消息可以表示 “1”、“2”、“3”、“4”、“5”、“6”、“7”、“8” 或 “9” 中的任意一条。可以分别解码成字符串 “A”、“B”、“C”、“D”、“E”、“F”、“G”、“H” 和 “I”。原创 2024-11-12 19:49:53 · 224 阅读 · 0 评论 -
【划分型DP-最优划分】力扣91. 解码方法
初始化dp[0] = 1,这是我们边界条件的处理,我们可以想象i=2,只有两个字符的时候,如果我们将这两个字符作为一种解码方式,那么此时dp[2]由dp[0]状态转移而来,所以我们可以认为dp[0]应当初始化为1。我们定义dp[i]为前 i 个字符的解码方式数量,而dp[i]可以由dp[i-1]也可以由dp[i-2]状态转移而来,当我们将最后一个字符作为一个解码方法的时候,这时候由dp[i-1]转移而来,当把后两个字符作为一个解码方法,由dp[i-2]转移而来。输入:s = “12”输入:s = “06”原创 2024-11-12 09:07:37 · 237 阅读 · 0 评论 -
【划分型DP-最优划分】力扣2767. 将字符串分割为最少的美丽子字符串
最重要的是回溯的思路,我们定义dfs(i)的含义是从第i个字符后的字符串被分割成最少的美丽子字符串的个数,所以我们可以思考,我们从第0个字符开始,举个例子,如果找到了一个5的二进制表示101,那么也就是说,在这个回溯中,我们dfs(0)也就是dfs(3)+1,然后dfs(3)会继续往上回溯。那么既然使用了回溯,就要知道在回溯的末端我们该如何处理,在回溯末端我们刚好可以分割完字符串为美丽数组,那么就返回0,也就代表这个回溯的过程是可行的。解释:我们可以将输入字符串分成 [“1”, “1”, “1”]。原创 2024-11-11 22:41:19 · 225 阅读 · 0 评论 -
【划分型 DP-最优划分】力扣2707. 字符串中的额外字符
我们倒序遍历,在每一次遍历的开始,我们需要初始化dp[i],dp[i]的初始值可以由dp[i+1]+1状态转移而来。的含义是我们从s[i]开始的长度为word.size()的字符串是否和字典的单词匹配,如果匹配的话,并且dp[i+word.size()]小于dp[i],就更新dp[i]为dp[i+word.size()]。解释:将 s 分成两个子字符串:下标从 0 到 3 的 “leet” 和下标从 5 到 8 的 “code”。最后返回dp[0],代表从字符串s的最少未匹配字符。原创 2024-11-09 17:10:13 · 398 阅读 · 0 评论 -
【划分型 DP-最优划分】【腾讯笔试压轴】【hard】力扣132. 分割回文串 II
我们定义一个二维数组g[i][j]来表示字符串[i…在处理回文串的时候,需要注意我们要初始化g[i][j]都为true,这是为了避免额外判断:若初始化为 false,则需要额外处理长度为 1 或 2 的子串,代码的复杂度会增加。因为我们最终的目的就是求从0到(n-1)的字符串的最小分割次数,那么我们求0到j的最小分割次数就可以从前面的状态转换而来。我们这时候遍历下标i,目的是判断从i+1到j这字符串是否是回文,如果是回文的话,那么从0到j这个字符串的最小分割次数,不就是0到i的最小分割次数加上1吗。原创 2024-11-08 23:03:10 · 382 阅读 · 0 评论 -
【划分型 DP】力扣139. 单词拆分
我们首先在外层循环遍历i,代表着遍历字符串,然后内层循环j的作用是来判断该字符串前j个字符组成的字符串能否被拆分成字典里的单词,并且判断第j+1个字符后的单词是否在字典里。输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]解释: 返回 true 因为 “applepenapple” 可以由 “apple” “pen” “apple” 拼接成。注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。原创 2024-11-08 01:36:32 · 342 阅读 · 0 评论 -
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
首先为什么我们要向栈中推入一个-1,实际上这代表着从字符串第0个字符开始计数,然后当发现右括号找不到左括号,也就是栈st为空的时候,就将右括号坐标i填入到栈中,代表着从第i+1个元素开始计数。给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。栈的大小在最坏情况下会达到 n,因此空间复杂度为 O(n)。,n 是给定字符串的长度。解释:最长有效括号子串是 “()()”解释:最长有效括号子串是 “()”输入:s = “)()())”输入:s = “(()”原创 2024-11-07 14:57:11 · 238 阅读 · 0 评论 -
【数据结构-合法括号字符串】力扣678. 有效的括号字符串
遍历完字符串了以后,可能会存在还有未匹配的左括号,我们要做的就是将他与星号进行匹配,那么我们就记录栈顶元素,也就是他们各自的索引,由于星号这时候充当的是变成右括号,那么星号的索引必定要大于左括号才可以,如果st1的栈顶索引大于st2的栈顶索引,那么就会返回false,因为这时候找不到一个星号和这个左括号进行匹配。当我们遍历到左括号或者星号的时候,我们就将他的索引推入栈中,当我们遍历到右括号的时候,我们优先将他与左括号进行匹配,没有左括号我们才用星号去匹配。任何右括号 ‘)’ 必须有相应的左括号 ‘(’。原创 2024-11-06 22:59:24 · 377 阅读 · 0 评论 -
搞懂c#的委托与事件
调用 Interlocked.CompareExchange(ref _myEvent, updated, original),尝试将 _myEvent 更新为 updated,但前提是 _myEvent 的当前值没有被其他线程修改(即 _myEvent 仍等于 original)。适用于返回类型的委托,例如 Func。3.因为是数组,所以remove(-=)的复杂度是O(n),remove的时候,从后往前遍历。我们无法保证委托一定不是空的,委托如果是空的,在运行的时候会报错,我们可以采用。原创 2024-11-05 19:58:59 · 1416 阅读 · 0 评论 -
【数据结构-合法括号字符串】力扣856. 括号的分数
由于一个左括号对应一个右括号,那么我们在遍历字符串s的时候,如果遍历到左括号,那么就往栈中推入0,当推入右括号的时候,匹配对应的左括号,当这对括号是深度最深的括号的时候,那么他们的分数就是1,否则就将分数乘以2,加到浅一层深度的左括号中。我们通过这种方法,可以找到从左往右第二个左括号和第一个右括号形成一个括号对,然后深度是1,最终他贡献的分数就是2,然后从左往右第四个左括号和他右边的右括号形成一个括号对,深度是2,最终他贡献的分数就是4。举个例子:输入: “(()(()))”输入: “(()(()))”原创 2024-11-05 16:41:57 · 218 阅读 · 0 评论 -
【数据结构-合法括号字符串】【华为笔试题】力扣1190. 反转每对括号间的子串
让我们来模拟,当遍历s到第一个左括号的时候,他根据pair记录,查找到最外层有括号位置,然后遍历方向改变成向左,这时候遇到i,ret = “i”,然后遍历到内层有括号,索引转换到最内层左括号,方向向右,这时候一一推入’l’,‘o’,‘v’,‘e’,此时ret = “ilove”,然后遇到内层有括号,他根据pair将索引转换到内层左括号,方向向左,然后加入元素’u’,此时ret就是"iloveu"。预处理出括号的对应关系的序列的时间复杂度为 O(n),遍历字符串的时间复杂度同样为 O(n)。原创 2024-11-05 00:49:55 · 539 阅读 · 0 评论 -
【数据结构-邻项消除】力扣1717. 删除子字符串的最大得分
该while是贪心的思想的核心,我们因为已经假设ab的得分较大,那么当遍历字符是a的时候,我们直接记录a的数量,当字符是b的时候,并且在该部分字符串中,依旧存在a,那么他们就最终能构成字符串"ab"。我们记录完删除"ab"得到的得分后,还要记录删除"ba"得到的得分,这取决于在删除完"ab"操作后,剩余的a和b的数量的较小值乘以y。然后再定义一个栈st2,遍历处理过一遍的字符串st1,遍历里面的字符,逐一删除掉较小的分的字符串,并加上相应的得分。首先核心思路不变,先删除得分较大的字符串。原创 2024-11-01 01:52:11 · 446 阅读 · 0 评论 -
【数据结构-邻项消除】力扣735. 小行星碰撞
这道题的思路就是,我们遍历数组asteroids,将里面的所有元素一一与栈顶元素比对,如果遍历的元素a是负数,那么就会不断和栈中的元素进行比对,只要栈顶元素是正数且绝对值小于a,则会爆炸,也就是弹出栈,直到a遇到比自己大的反方向的行星自己爆炸或者栈顶的行星方向与自己相同,则停止while循环(因为当遇到和自己同方向的行星,说明栈中现有的行星没有反方向的),这时候如果行星没有发生爆炸,还存在,那么就将它推入栈中。碰撞规则:两个小行星相互碰撞,较小的小行星会爆炸。解释:2 和 -5 发生碰撞后剩下 -5。原创 2024-10-31 17:38:31 · 396 阅读 · 0 评论 -
【数据结构-邻项消除】力扣1209. 删除字符串中的所有相邻重复项 II
我们定义一个栈counts,栈顶元素来表示目前构造后的字符串的最右边元素的数量,在构造过程中,只要j等于0或者推入元素和字符串最右边元素不一样,则令counts栈顶新推入1代表该元素连续的数量。我们可以通过模拟栈的方法,在每层栈元素中,储存字符和其数量,我们在遍历字符串s的时候,如果推入元素和栈顶元素相同,则数量+1,然后检查是否数量等于k,如果等于则将该层栈元素弹出,否则推入目前遍历的字符并且令数量为1。先删除 “eee” 和 “ccc”,得到 “ddbbbdaa”最后删除 “ddd”,得到 “aa”原创 2024-10-29 22:01:01 · 216 阅读 · 0 评论 -
【数据结构-邻项消除】力扣2216. 美化数组的最少删除数
我们定义一个变量i来记录在构造完美数组中的索引,当i为偶数的时候,我们就让原数组的元素为preNum,如果当i为奇数,并且nums不等于preNum的时候,那么我们可以将num放到i位置,然后我们让i++指向下一个位置。解释:可以删除 nums[0] 或 nums[1] ,这样得到的 nums = [1,2,3,5] 是一个美丽数组。解释:可以删除 nums[0] 和 nums[5] ,这样得到的 nums = [1,2,2,3] 是一个美丽数组。输入:nums = [1,1,2,2,3,3]原创 2024-10-29 01:08:36 · 372 阅读 · 0 评论 -
【状态机DP】力扣1186. 删除一次得到子数组最大和
呢,因为我们在之前dp[i][0]中如果前面dp[i-1][0]为负数,则以arr[i]重新开始计算,但是由于现在的dp[i][1]要求必须删除一个元素,那么不可能从arr[i]开始算起,但是没有删除任何元素。我们定义一个动态规划数组dp,dp[i][0]代表以arr[i]结尾的子数组,并且没有删除过元素,dp[i][1]代表以arr[i]结尾的子数组,并且删除过元素。解释:我们可以选出 [1, -2, 0, 3],然后删掉 -2,这样得到 [1, 0, 3],和最大。所以我们有状态转移方程。原创 2024-10-27 12:20:08 · 385 阅读 · 0 评论 -
【状态机DP】【记忆化搜索&&1:1翻译递归&&空间优化】力扣2771. 构造最长非递减子数组
然后我们这时候进行判断,看我们现在nums[j][i]与nums1[i-1]和nums2[i-1]进行比较,如果大于等于他们,则说明我们这时候的最大非递减子序列长度就是要么dfs(i-1, 0)+1,要么就是dfs(i-1, 1)+1,取两者最大值即可。,f[i][j]都是由上一轮i-1转换而来,由于我们在使用一位数组的时候,会存在覆盖,使f[j]变成这一轮计算过的值而不是上一轮,所以我们在每一轮开始的时候,通过两个变量t0和t1来记录上一轮的f[0]和f[1]供着一轮的状态转移使用。原创 2024-10-23 16:54:38 · 829 阅读 · 0 评论 -
【状态机DP】【hard】力扣1363. 形成三的最大倍数
还有一个重要的问题是,我们在最后对ans进行reverse操作,那么我们能不能在i从0-9循环,进行从9-0倒序循环,然后不使用reverse操作呢?答案是不可以,因为涉及到我们的remove_mod操作,如果使用倒序,那么会优先删除最大的符合余数条件的字符,而我们要删除的是最小的符合条件的字符,这样才能让ans达到最大。给你一个整数数组 digits,你可以通过按 任意顺序 连接其中某些数字来形成 3 的倍数,请你返回所能得到的最大的 3 的倍数。输入:digits = [0,0,0,0,0,0]原创 2024-10-23 00:38:27 · 499 阅读 · 0 评论 -
【状态机DP】【贪心】力扣376. 摆动序列
表示nums[i]可以接在down[i-1]的最长下降摆动子序列后面的情况,那怎么能说明down[i-1]中的最长下降摆动子序列的最后一个元素不大于nums[i-1]呢,实际上我们可以采用反证的方法,如果down[i-1]中最长下降摆动子序列的最后一个元素大于nums[i-1]的话,那么nums[i-1]则会成为down[i-1]的最后一个元素。其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8)。,其中 n 是序列的长度。原创 2024-10-20 15:53:29 · 358 阅读 · 0 评论 -
【状态机DP】【记忆化搜索及翻译递推】【空间优化】力扣3290. 最高乘法得分
你的得分将是 a[0] * b[i0] + a[1] * b[i1] + a[2] * b[i2] + a[3] * b[i3] 的值。我们在定义递推的状态转换方程的时候,有两种情况,选择或者不选择b[i],如果选择了b[i],那么这时候a[j]会和b[i]相乘,a[j]和b[i]都被使用了,对应。选择下标 0, 1, 2 和 5。输入: a = [3,2,5,6], b = [2,-6,4,-5,-3,2,-7]输入: a = [-1,4,5,-2], b = [-5,-1,-3,-2,-4]原创 2024-10-17 20:57:51 · 659 阅读 · 0 评论 -
【状态机DP】力扣2745. 构造最长的新字符串
这三个整数表示你有 x 个 “AA” 字符串,y 个 “BB” 字符串,和 z 个 “AB” 字符串。解释:我们可以按顺序连接 “AB” ,“AB” ,“AA” ,“BB” ,“AA” ,“BB” 和 “AA” ,得到新字符串 “ABABAABBAABBAA”。解释: 我们可以按顺序连接 “BB” ,“AA” ,“BB” ,“AA” ,“BB” 和 “AB” ,得到新字符串 “BBAABBAABBAB”。,如果当上一个状态不是AA,是BB或者AB的时候,那么后面可以跟AA或AB,对应。原创 2024-10-16 21:00:01 · 393 阅读 · 0 评论 -
【状态机DP】力扣1493. 删掉一个元素以后全为 1 的最长子数组
我们可以定义两个数组,一个pre[i]来记录以i结尾的最大连续1的数量,一个suf[i]用来记录以i开头的最大连续1的数量,然后我们遍历每个元素作为删除的元素,然后就可以知道如果删除了这个元素,那么pre[i-1]和suf[i+1]的和就是最大连续1的数量。解释:删掉位置 4 的数字后,[0,1,1,1,1,1,0,1] 的最长全 1 子数组为 [1,1,1,1,1]。假设nums = {1, 1, 0, 1, 1, 1, 0, 1, 1}输入:nums = [0,1,1,1,0,1,1,0,1]原创 2024-10-15 21:16:42 · 582 阅读 · 0 评论 -
【状态机DP】力扣309. 买卖股票的最佳时机含冷冻期
dp[i][2]是不持有股票但不处于冷冻期,说明我们没有进行买入或者卖出的操作,不然在第i天结束后会持有股票或者处于冷冻期。dp[i][0]代表的是持有股票,也就是第i天结束后是持有股票的。那么如何在第i天结束后持有股票呢?dp[i][1]是不持有股票且处于冷冻期,如何才能让在第i天结束的时候处于冷冻期呢?只有在第i天进行了卖的操作,那么第i-1天结束的时候,我们肯定是持有股票的,所以有。由于最后我们股票需要卖出才能获得最大收益,所以我们只要取dp[n-1][1], dp[n-1][2]两者的最大值即可。原创 2024-10-14 23:02:45 · 676 阅读 · 0 评论 -
【状态机DP】【hard】力扣188. 买卖股票的最佳时机 IV
我们定义动态数组buy[i][j],含义是在第i天的时候,持有股票(不一定是当天买)并储存最大利润,然后一共有完整的交易j次(完整的交易指的是经过买和卖)。解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2。有几个细节要注意的是,我们是从第0天而不是第一天开始,然后我们第0天的时候,不可能有完整的操作(最多进行一次买操作),所以第0天。输入:k = 2, prices = [3,2,6,5,0,3]原创 2024-10-14 17:46:51 · 1492 阅读 · 0 评论 -
【状态机DP】【hard】【字节面试题】力扣123. 买卖股票的最佳时机 III
buy1的意思是,我们可以对今天的股价选择买或者不买,买的话利润就是-prices[i],不买利润不变,我们要保证最大利润。然后sell1可以选择今天卖或者不卖,不卖的话利润不变,如果卖的话,就将买造成的负利润加上当前卖出的价格,就是我们现在的利润,我们依旧要保证第一次卖的时候,利润要最大。随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3。输入:prices = [3,3,5,0,0,3,1,4]原创 2024-10-13 18:43:39 · 425 阅读 · 0 评论 -
【数据结构-栈】【哈希+栈】【hard】【阿里,字节,快手,华为面试题】力扣895. 最大频率栈
在push函数中,我们让freq[val]++代表这个元素出现的频率增加了一次,st[freq[val]].push(val),代表我们在储存频率为freq[val]的栈中加入元素val。//返回 4 ,因为 4, 5 和 7 出现频率最高,但 4 是最接近顶部的。堆栈变成 [5,7,5,7,4]。输出:[null,null,null,null,null,null,null,5,7,5,4]//堆栈是 [5,7,5,7,4,5]//堆栈是 [5,7,5,7,4]//堆栈是 [5,7,5,7]原创 2024-10-12 14:35:15 · 1202 阅读 · 0 评论 -
【数据结构-栈】【贪心】力扣2434. 使用机器人打印字典序最小的字符串
我们可以思考,将t想象成一个栈,先进后出,然后当栈顶元素的值,也就是t的末尾的值比字符串s中的任何一个字符都要小的时候,那么我们就要将栈顶元素推入p中,也就是写出来的字符串,这样才能保证最小字典序列。,由于0代表a,1代表b…执行第一个操作四次,得到 p=“” ,s=“” ,t=“bdda”。执行第一个操作三次,得到 p=“” ,s=“” ,t=“zza”。执行第一个操作,得到 p=“ab” ,s=“” ,t=“c”。执行第二个操作,得到 p=“abc” ,s=“” ,t=“”。原创 2024-10-12 02:10:10 · 416 阅读 · 0 评论 -
【数据结构-栈】【差分思想-延迟更新优化】力扣1381. 设计一个支持增量操作的栈
第二次将前k+3个元素增加了val2,也就是add[k+2]=val2,那么他们共同覆盖的范围是不是前k+1个元素,那么也就是说,前k+1个元素增量是val1+val2,在第k+2到k+3个元素,增量是val2。这时候假设我们进行三次pop()操作,那么stk[k+2] += add[k+2],然后add[k+2]将增量传给add[k+1](使用+=),这时候stk[k+1] += add[k+1],依旧是加上val2。// 返回 2 --> 返回栈顶值 2,栈变为 [1]// 栈变为 [1, 2, 3]原创 2024-10-11 18:11:08 · 776 阅读 · 0 评论 -
【数据结构-栈】【位运算优化】力扣3170. 删除星号以后字典序最小的字符串
我们按顺序遍历字符串,在遍历过程中,如果字符不为*,那么就在栈数组对应的栈推入这个字符的位置。在循环字符串s的过程中,字符不为星号,则让mask对应位置变为1,说明这个字母存在。我们查找到字典序最小的字符所处的栈后,栈顶的元素代表这当前最靠右的字符的位置,我们在字符串s中将这个字符。:O(n+∣Σ∣),其中 n 是 s 的长度,∣Σ∣ 为字符集合的大小,本题字符均为小写字母,所以 ∣Σ∣=26。:O(n∣Σ∣),其中 n 是 s 的长度,∣Σ∣ 为字符集合的大小,本题字符均为小写字母,所以 ∣Σ∣=26。原创 2024-10-10 20:14:35 · 565 阅读 · 0 评论
分享