刷题交流|子串与子序列相关题目的解题技巧讨论(如何区分,不出错)
1406
发布于 未知归属地

基础

子串与子数序列共同点与区别:
共同点:二者均不可改变元素在原序列/数组中的顺序(相对位置)
不同点:
子串或子数组:必须连续
子序列:可以不连续


解题时的区别

均考虑使用动态规划的前提下去对比(初学,其他的也不太会...)

1.子串相关题目

解题思路:

当前状态一定由上一个临近状态推得,
如:
一维的情况下 dp[i] 只能由 dp[i-1] 计算得到,若在原数组中i与i-1不满足题目要求,则不需要更新dp[i] (保持初始值,一般是0)
二维的情况下 dp[i][j] 只能由 dp[i+1][j-1] (回文的情况)/dp[i-1][j-1] (两个数组或字符串比较的情况) 计算得到,若在原数组中i与j不满足题目要求,则不需要更新dp[i][j] (保持初始值,一般是0)

1.1 最长连续递增子序列(可翻译为 最长递增子数组)

1.定义状态:dp[i]为以i结尾的连续递增子序列长度
2.状态转移方程:因为是连续的,所以dp[i]只能由dp[i-1]推得,因此只有在nums[i] > nums[i-1]时,才需要更新 dp[i] = dp[i-1] + 1

1.2 最长重复子数组

1.定义状态:dp[i][j]为 数组nums1 以i结尾,数组nums2 以j结尾的,重复子数组长度
2.状态转移方程:因为是连续的,所以dp[i][j]只能由dp[i-1][j-1]推得,因此只有在nums1[i] == nums2[j]时,才需要更新 dp[i][j] = dp[i-1][j-1] + 1

1.3 最长回文子串长度

1.定义状态:dp[i][j]为 字符串s 从i位置到j位置的回文子串长度
2.状态转移方程:因为是连续的,所以dp[i][j]只能由dp[i+1][j-1]推得,因此只有在s[i] == s[j]时,才需要更新 dp[i][j] = dp[i+1][j-1] + 2

2.子序列相关题目

1.1 最长递增子序列

1.定义状态:dp[i]为以i结尾的递增子序列长度
2.状态转移方程:因为是不需要连续的,所以dp[i]能由dp[0...i-1] 计算得到,记dp[0...i-1]为dp[j],因此在nums[i] > nums[j]时,更新 dp[i] = max(dp[j] + 1,dp[i])

1.2 最长公共子序列

1.定义状态:dp[i][j]为 数组nums1 以i结尾,数组nums2 以j结尾的,重复公共长度
2.状态转移方程:因为是不需要连续的,所以dp[i][j]能由dp[i-1][j-1]、dp[i-1][j],dp[i][j-1]推得,因此在nums1[i] == nums2[j]时,需要更新 dp[i][j] = dp[i-1][j-1] + 1,否则,dp[i][j] = max(dp[i-1][j],dp[i][j-1])。
ps:可以理解为如果nums1[i] != nums2[j],则当前的状态由之前的状态延续且不做改变,因为不需要连续,所以之前的状态在后续更新中可以继续使用。

1.3 最长回文子序列

1.定义状态:dp[i][j]为 数组s 从i位置到j位置的回文序列度
2.状态转移方程:因为是不需要连续的,所以dp[i][j]能由dp[i+1][j-1],dp[i][j-1],dp[i+1][j]推得,因此在s[i] == s[j]时,需要更新 dp[i][j] = dp[i+1][j-1] + 2,否则,dp[i][j] = max(dp[i][j-1], dp[i+1][j])


结尾

初学的一些总结,不够深入,欢迎大佬又更深入更精辟的结论来探讨。

评论 (0)