最长递增子序列

71 阅读1分钟

题目

动态规划

public class Main {
    public static void main(String[] args) {

        Main main = new Main();
        int [] nums = new int[]{10, 9, 2, 5, 3, 7, 101, 18};
        main.lengthOfLIS(nums);
    }

    public int lengthOfLIS(int[] nums) {

        int [] dp = new int[nums.length];

        int max = Integer.MIN_VALUE;
        for(int i = 0; i < nums.length; i ++) {
            if (i == 0) {
                dp[i] = 1;
            } else {
                int tempMax = Integer.MIN_VALUE;
                for(int j = i; j >= 0; j --) {
                    // 找到所有比nums[i]小的元素
                    if (nums[j] < nums[i]) {
                        tempMax = Math.max(1 + dp[j], tempMax);
                    }
                }
                dp[i] = Math.max(1, tempMax);
            }
            max = Math.max(max, dp[i]);
        }
        return max;
    }
}

基本思路

  1. 每个i位置的最长递增子序列, 如果在该位置之前存在位置j, 使得nums[j] < nums[i], 那么该位置的最长的递增子序列的可能答案之一就是dp[j] + 1, 但是注意, 这种j可能存在不只一次, 因此要枚举出所有的j, 选出最大的dp[j], 此时dp[i] = max_dp[j] + 1;

如果找不到这样的j, 例如当前元素是已知元素的最小值, dp[i] = 1, 说明以i位置结尾的最长递增子序列长度就是1

  1. 需要明确dptable中, 每个位置的含义, 不要弄混淆, 本题中的含义dp[i]就是以i结尾的最长递增子序列, 注意是以i结尾, 而是i之前的任意最大值