子序列問題可以按照動態規劃的思想去寫。
子序列問題類型
子序列 是由數組派生而來的序列,刪除(或不刪除)數組中的元素而不改變其余元素的順序。
例如,[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循環。