子串与子数序列共同点与区别:
共同点:二者均不可改变元素在原序列/数组中的顺序(相对位置)
不同点:
子串或子数组:必须连续
子序列:可以不连续
均考虑使用动态规划的前提下去对比(初学,其他的也不太会...)
当前状态一定由上一个临近状态推得,
如:
一维的情况下 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.定义状态:dp[i]为以i结尾的连续递增子序列长度
2.状态转移方程:因为是连续的,所以dp[i]只能由dp[i-1]推得,因此只有在nums[i] > nums[i-1]时,才需要更新 dp[i] = dp[i-1] + 1
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.定义状态: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
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.定义状态: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.定义状态: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])
初学的一些总结,不够深入,欢迎大佬又更深入更精辟的结论来探讨。