动态规划
文章平均质量分 61
动态规划
hlc@
这个作者很懒,什么都没留下…
展开
-
【划分型DP】力扣2008. 出租车的最大盈利
乘客信息用一个下标从 0 开始的二维数组 rides 表示,其中 rides[i] = [starti, endi, tipi] 表示第 i 位乘客需要从地点 starti 前往 endi ,愿意支付 tipi 元的小费。输入:n = 20, rides = [[1,6,1],[3,10,2],[10,12,3],[11,12,2],[12,15,2],[13,18,1]],其中 m 是 rides 的长度,n 是地点数目。输入:n = 5, rides = [[2,5,4],[1,5,1]]原创 2024-11-26 18:52:00 · 302 阅读 · 0 评论 -
【划分型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 评论 -
【划分型 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-最优划分】力扣LCR 165. 解密数字
这道题和将字母翻译为数字的逻辑一样,我们只需要定义dp[i]为前i个字符组成的字符串所能解密的字母个数。然后我们开始遍历i,以第i个字符和第i-1个字符进行讨论,当curNum是0-5之间的时候,并且lastNum是1或2,我们可以将他们两个数字转化为一个字符。解释: 216612 解密后有 6 种不同的形式,分别是 “cbggbc”,“vggbc”,“vggm”,“cbggm”,“cqgbc” 和 “cqgm”如果curNum是其他数字,那么只有当lastNum为1的时候,这两个数字才能转化为一个字母。原创 2024-11-12 23:04:59 · 286 阅读 · 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 评论 -
【动态规划-划分型 DP】力扣2369. 检查数组是否存在有效划分
我们在遍历过程中,一旦发现此时最近的几个元素,能够满足三种有效划分情况的一种,我们根据在这几个元素之前是否也存在有效划分,如果存在,那么说明目前至少存在一种有效划分。通过对未压缩代码观察,我们发现我们在动态规划状态转移过程中,最多只用到当前元素和前面两个元素,那么说明我们可以用三个变量来储存这些状态,然后在遍历nums的过程中不断覆盖滚动。例如,子数组 [3,4,5] ,但是子数组 [1,3,5] 不符合要求。子数组 恰 由 3 个相等元素组成,例如,子数组 [4,4,4]。解释:该数组不存在有效划分。原创 2024-11-07 17:47:43 · 407 阅读 · 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】力扣1395. 统计作战单位数
作战单位需满足: rating[i] < rating[j] < rating[k] 或者 rating[i] > rating[j] > rating[k] ,其中 0 <= i < j < k < n。从队伍中选出下标分别为 i、j、k 的 3 名士兵,他们的评分分别为 rating[i]、rating[j]、rating[k]rating[i] < rating[j] < rating[k],则有iless * kmore种组合。n 名士兵站成一排。输入:rating = [2,5,3,4,1]原创 2024-10-23 15:45:32 · 229 阅读 · 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】力扣1262. 可被三整除的最大和
可能受到前面计算的影响,因为我们转移的dp是之前的状态,而如果直接使用dp,那么有的dp会被更新成目前状态,导致后续计算出错。没有选任何元素时,和为0是合法的解,并且0是可以被3整除的,所以我们在初始化时,令dp[0] = 0。解释:选出数字 1, 3, 4 以及 4,它们的和是 12(可被 3 整除的最大和)。解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。输入:nums = [3,6,5,1,8]输入:nums = [1,2,3,4,4]输入:nums = [4]原创 2024-10-21 22:25:41 · 351 阅读 · 0 评论 -
【状态机DP】力扣2786. 访问数组中的位置使分数最大
在访问位置i的时候,假设i是奇数,则最大的dp[1]有可能是从上一个最大dp[1]加上当前nums[i]转移而来,或者是从上一个最大dp[0]加上nums[i]减去x转移而来,由于nums[i]在题目中大于0,则cur无论如何都会比之前的dp[1]要大。对于这道题目,我们可以定义一个容量为2的dp数组来说明他的奇偶性,并储存最后移动的元素为偶数时得分的最大值和最后移动的元素为奇数时得分的最大值。输入:nums = [2,3,6,1,9,2], x = 5。注意 ,你一开始的分数为 nums[0]。原创 2024-10-21 18:02:47 · 559 阅读 · 0 评论 -
【状态机DP】1567. 乘积为正数的最长子数组长度
当nums[i]<0的时候,a[i]从b[i-1]+1转化而来,但是如果b[i-1]为0,也就是说以nums[i]结尾的最长负数子数组的长度为0,则说明a[i]不能通过之前的负数乘积来乘以当前负数的nums[i]来得到一个正数,那么由于当前nums[i]也是负数,所以当b[i-1]为0的时候,a[i]也为0。当nums[i]>0的时候,a[i]由a[i-1]+1转换而来,b[i]由b[i-1]转换而来,如果b[i-1]为0,那么b[i]也为0。输入:nums = [-1,-2,-3,0,1]原创 2024-10-20 17:21:14 · 359 阅读 · 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】力扣2222. 选择建筑的方案数
比方说,给你 s = “001101” ,我们不能选择第 1 ,3 和 5 栋建筑,因为得到的子序列是 “011” ,有相邻两栋建筑是同一类型,所以 不合 题意。遍历字符串s,假设每个元素为中间元素,定义cnt为之前的1的数量,定义count为字符串中总共的1的数量,res为有效方案数的总数。当s[I]为1的时候,这种情况下的有效方案数的数量为前面的0的数量和后面的0的数量的乘积,对应代码。当s[I]为0的时候,有效方案的数量为前面的1的数量和后面1的数量的乘积,对应代码。解释:没有任何符合题意的选择。原创 2024-10-17 11:54:30 · 374 阅读 · 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】力扣3259. 超级饮料的最大强化能量
你需要每小时饮用一种能量饮料来 最大化 你的总强化能量。然而,如果从一种能量饮料切换到另一种,你需要等待一小时来梳理身体的能量体系(在那个小时里你将不会获得任何强化能量)。对于f[i][0]可以从两个状态转换而来,一种是前一天喝的是A饮料,因为喝同一种饮料没有冷冻期,还有一种是前两天喝的是B饮料,那么前一天就是冷却期,得到状态转换方程。我们定义两种状态,一种是f[i][0]代表第i-2个小时使用能量A所具有的最大能量,一种是f[i][1]代表第i-2个小时使用能量B所具有的最大能量。原创 2024-10-16 15:37:42 · 377 阅读 · 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】力扣714. 买卖股票的最佳时机含手续费
我们可以定义两个状态f[i][0]和f[i][1]。f[i][0]代表第i天结束后并持有股票的最大利润,f[i][1]代表第i天结束后没有持有股票的最大利润。那么f[i][0]可以从两个状态转换而来,第一种是不操作,说明前一天结束的时候就已经持有股票,第二种是第i天买入了股票,说明前一天结束的时候没有持有股票。f[I][1]也可以从两个状态转换而来,第一种是不操作,说明前一天结束的时候依旧没有持有股票,第二种是第i天卖出了股票,说明前一天结束的时候持有股票。:O(n),其中 n 为数组的长度。原创 2024-10-15 15:59:03 · 336 阅读 · 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 评论 -
【动态规划-状态机 DP】力扣121. 买卖股票的最佳时机
我们假设每天都卖出,然后我们就希望在今天之前的最低价格买入,这样就会有最大的利润,每当我们发现了最小的价格,我们就假设一种情况在今天最小的价格买入,在以后的最高价格卖出,来获取今天之后可能的最大利润。每次卖出我们都要比较每次卖出的利润,记录最高利润,最后返回。解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5。为了求取股票最大利润,我们希望能尽量在最低的价格买入,在买入后的最高的价格卖出。输入:[7,1,5,3,6,4]原创 2024-10-12 16:08:34 · 252 阅读 · 0 评论 -
【动态规划-最长递增子序列(LIS)】【hard】力扣1671. 得到山形数组的最少删除次数
例如,如果当前序列为 1, 2, 3,新加入的元素也是 3,upper_bound 会找到序列末尾并在适当位置插入新的 3,从而维持非严格递增的性质。而lower_bound查找的是大于等于nums[i]的元素,所以nums[i]如果有与inc中相等的元素,会替换而不是推入,这保证了最长递增子序列是严格递增的。解释:一种方法是将下标为 0,1 和 5 的元素删除,剩余元素为 [1,5,6,3,1] ,是山形数组。输入:nums = [2,1,1,5,6,2,3,1]输入:nums = [1,3,1]原创 2024-10-09 23:08:26 · 379 阅读 · 0 评论 -
【动态规划-最长递增子序列(LIS)】力扣2826. 将三个组排序
一开始我们得到g=[1,2,4,5],然后遇到x=3,替换后g=[1,2,3,5],这时候g就是虚拟的递增子序列,因为很明显nums中没有这么一个递增子序列。接着遇到x=4,替换掉g中的5,g=[1,2,3,4,7]。最后遇到x=6,替换掉了g中的最后一个元素7,g=[1,2,3,4,6],这时候我们的最长子序列才真正变成了[1,2,3,4,6]。举个例子:nums = [1,2,4,5,3,7,4,6]输入:nums = [1,3,2,1,3,3]输入:nums = [2,2,2,2,3,3]原创 2024-10-09 17:32:19 · 784 阅读 · 0 评论 -
【动态规划-最长递增子序列(LIS)】力扣673.最长递增子序列的个数
就说明发现了更长的公共子序列,那么这个时候,我们就重置count[i]为count[j],之所以重置为count[j]是因为count[j]代表着之前以nums[j]结尾的最长公共递增子序列的个数,那么有count[j]个最长公共递增子序列再加上当前的nums[i],就有count[j]种以nums[i]结尾的最长公共递增子序列。然后再继续遍历以nums[i]结尾的最长公共递增子序列,如果发现了有相同长度的公共递增子序列,就加上这个以nums[j]结尾的最长公共子序列的数量count[j]。原创 2024-10-09 01:00:41 · 287 阅读 · 0 评论 -
【动态规划-最长公共子序列(LCS)】【hard】力扣1092. 最短公共超序列
在第一次判断的过程中,指针i指向str1的c,指针j指向str2的b,由于str1和str2的LCS是ab,那么b作为LCS的一部分,那么推入b就会影响到LCS(如果推入b后,那么构造LCS就没有意义,构造LCS的目的是让指针在都指向LCS的部分的时候,可以只推入一个元素,然后同时让i和j都-1)。str2 = “cab” 是 “cabac” 的一个子串,因为我们可以删去 “cabac” 末尾的 “ac” 得到 “cab”。输入:str1 = “aaaaaaaa”, str2 = “aaaaaaaa”原创 2024-10-08 22:31:04 · 490 阅读 · 0 评论 -
【动态规划-4.2 最长递增子序列(LIS)】力扣300. 最长递增子序列
我们需要的是len的长度,len++的来源于nums[i]大于d[len],如果d[len]被替换成更小的nums[i],会对后续的len++有正面影响,如果nums[i]替换掉的不是d[len],假设是d[len-1],那么会减小d[len-1]的值,在后续的nums[i]的替换中,会变得更容易被选为pos,从而替换d[len-1],然后对后续的len++有正面影响。由于nums[i]经过二分查找,肯定比d[pos+1]要小,所以在相同长度的子序列中,末尾最小元素就为nums[i]。:O(nlogn)。原创 2024-10-08 02:10:46 · 950 阅读 · 0 评论 -
【动态规划-最长公共子序列(LCS)】【hard】力扣1458. 两个子序列的最大点积
比方说,[2,3,5] 是 [1,2,3,4,5] 的一个子序列而 [1,5,3] 不是。这道题是LCS的变形,dp[i][j] 表示使用 nums1 的前 i 个元素和 nums2 的前 j 个元素时,能够得到的最大点积。解释:从 nums1 中得到子序列 [2,-2] ,从 nums2 中得到子序列 [3,-6]。输入:nums1 = [2,1,-2,5], nums2 = [3,0,-6]输入:nums1 = [-1,-1], nums2 = [1,1]最后返回dp[m][n]。原创 2024-10-06 21:34:49 · 564 阅读 · 0 评论 -
【动态规划-最长公共子序列(LCS)】力扣1035. 不相交的线
但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相交。输入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]输入:nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。输入:nums1 = [1,4,2], nums2 = [1,2,4]原创 2024-10-06 20:48:16 · 483 阅读 · 0 评论
分享