子序列问题写法
子序列问题可以按照动态规划的思想去写。
子序列问题类型
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。
例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
写法思路
创建两层for循环,外层为for(int i=0;i<n;i++);内层为for(int j=0;j<i;j++)。
然后就写转移方程即可。
例题:NO.300. 最长递增子序列
题目:
链接:
https://leetcode.cn/problems/longest-increasing-subsequence/description/
代码:
class Solution {
// 状态表示: 以i结束的序列,最长严格递增序列的长度;
public int lengthOfLIS(int[] nums) {
int n=nums.length;
int[] dp=new int[n];
// 初始化:
for(int i=0;i<n;i++) dp[i]=1;
int ret=1;
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
// 转移方程:
if(nums[i]>nums[j]){
dp[i]=Math.max(dp[i],dp[j]+1);
}
}
ret=Math.max(ret,dp[i]);
}
return ret;
}
}
状态表示:
以i结束的序列,最长严格递增序列的长度;
转移方程:
长度为1时,dp[i]=1; 长度大于1时,满足(nums[i]>nums[j],则dp[i]=Math.max(dp[i],dp[j]+1); 初始化: 因为长度>=1,所以每一个以i结尾的序列,最小长度为1,于是令全数组长度为1. 填表顺序: 从左往右依次填写。
总结:
子序列问题包含子数组问题,这类问题是动态规划的一种形式(当然也可以用其他方法写),只不过是变成了双层for循环。