[39] (Dynamic Programming-Subsequence Problem Solving Template) The longest increasing subsequence | the longest palindrome subsequence (LC 300 | 516)

Dynamic programming-subsequence problem solving template

1. One-dimensional dp array

template:

int n = array.length;
int[] dp = new int[n];

for (int i = 1; i < n; i++) {
    
    
    for (int j = 0; j < i; j++) {
    
    
        dp[i] = 最值(dp[i], dp[j] + ...)
    }
}

The meaning of dp[i]: In the sub-array array[0...i], the length of the target subsequence ending in array[i] is dp[i]. (Similar to this)

Example: the longest increasing subsequence

Problem Description

Give you an integer array nums and find the length of the longest strictly increasing subsequence.

A subsequence is a sequence derived from an array, deleting (or not deleting) elements in the array without changing the order of the remaining elements. For example, [3,6,2,7] is a subsequence of the array [0,3,1,6,2,2,7].

Problem-solving ideas

Define dp[i] to represent the length of the longest increasing subsequence ending with nums[i] . If dp[i] is required, then max(dp[1],dp[2],…,dp [i-1]), assuming max(dp[1],dp[2],…,dp[i-1]) = dp[j], then if nums[i]> nums[j], then dp[ i] = dp[j] + 1, otherwise dp[i] remains unchanged.

Code

class Solution {
    
    
    public int lengthOfLIS(int[] nums) {
    
    
        int n = nums.length;//求出数组元素个数
        if(n == 0) //若数组为空,返回0
            return 0;
        int dp[] = new int[n];//dp[i]表示以nums[i]结尾的最大递增子序列长度
        int result = -1;
        for(int i=0;i<n;i++){
    
    
            dp[i] = 1; //初始都为1
            for(int j=0;j<i;j++){
    
    //dp[0]开始
                if(nums[i]>nums[j])//若nums[i]>nums[j]则dp[i]可以为dp[j]+1,否则对dp[i]不做处理
                    dp[i] = Math.max(dp[i],dp[j]+1);
            }
            result = Math.max(dp[i],result);
        }
        return result;
    }   
}

Time complexity: O(n^2)
Space complexity: O(n)

2. Two-dimensional dp array

template:

int n = arr.length;
int[][] dp = new dp[n][n];

for (int i = 0; i < n; i++) {
    
    
    for (int j = 1; j < n; j++) {
    
    
        if (arr[i] == arr[j]) 
            dp[i][j] = dp[i][j] + ...
        else
            dp[i][j] = 最值(...)
    }
}

The meaning of dp[i][j]:

  • When two strings/arrays are involved: In the sub-array arr1[0...i] and the sub-array arr2[0...j], the length of the sub-sequence we require is dp[i][j]. Example: edit distance, longest common subsequence...
  • When only one string/array is involved: In the sub-array array[i...j], the length of the sub-sequence we require is dp[i][j]. Example: the longest palindrome subsequence...

Example: the longest palindrome subsequence

Problem Description

Given a string s, find the longest palindrome subsequence, and return the length of the sequence. It can be assumed that the maximum length of s is 1000.

Problem-solving ideas

Define dp[i][j] as the length of the longest palindrome subsequence in the substring s[i,...,j], assuming that dp[i+1][j-1] is known at this time, then if s[i ]==s[j], then dp[i][j] = dp[i+1][j-1] + 2; otherwise it is equal to max(dp[i+1][j],dp[i][ j-1]).

Code

class Solution {
    
    
    public int longestPalindromeSubseq(String s) {
    
    
        int n = s.length();
        if(n == 0) return 0;
        int dp[][] = new int[n][n];
        for(int i=n-1;i>=0;i--){
    
    
            dp[i][i] = 1;// i==j时回文串长度为1
            for(int j=i+1;j<n;j++){
    
    
                if(s.charAt(i) == s.charAt(j))
                    dp[i][j] = dp[i+1][j-1]+2;
                else
                    dp[i][j] = Math.max(dp[i+1][j],dp[i][j-1]);
            }
        }
        return dp[0][n-1];
    }
}

Guess you like

Origin blog.csdn.net/qq_43424037/article/details/114230672