代码随想录算法训练营 day 52: ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组

46 阅读1分钟

300. Longest Increasing Subsequence

dp[i]为以i为结尾的最长递增子序列,那么要计算dp[i],需要以j遍历从0到i-1, 在每层循环中:

  1. 若nums[j] < nums[i], 意味着j元素可以参与构成以i为结尾的子序列,那么dp[i] = max(dp[i], dp[j] + 1)
  2. 若nums[j] > nums[i],跳过,因为j元素不可能参与构成i为结尾的子序列。

最后,用一个result来存放最长的子序列长度。

class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums.length == 1) {
            return nums.length;
        }
        int[] dp = new int[nums.length];

        Arrays.fill(dp, 1);

        int res = 0;

        for(int i=1; i<nums.length; i++) {
            for(int j=0; j<i; j++) {
                if(nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }

            if(dp[i] > res) {
                res = dp[i];
            }
        }

        return res;
        
    }
}

674. Longest Continuous Increasing Subsequence 这题不难但一开始用了两层循环,比较好理解。dp[i]为i为结尾的连续递增子序列长度,用一个j从i-1 遍历,走到大于nums[i]的元素时,break 一层循环的话,dp[i] = dp[i-1] + 1,仅在nums[i] > nums[j]时成立。

class Solution {
    public int findLengthOfLCIS(int[] nums) {
        if(nums.length == 1) {
            return 1;
        }

        int[] dp = new int[nums.length];
        Arrays.fill(dp, 1);

        int result = 0;

        for(int i=1; i<nums.length; i++) {
            if(nums[i] > nums[i-1]) {
                dp[i] = dp[i-1] + 1;
            }

            if(dp[i] > result) {
                result = dp[i];
            }
        }

        return result;
        
    }
}

718. Maximum Length of Repeated Subarray

这题要用二维dp数组,但只用对角线元素。dp[i][j]为在数组A的i-1元素为结尾,数组B的j-1元素为结尾,时的最长公共子序列。 dp[i][j]只能用dp[i-1][j-1] 推出,为dp[i][j] = dp[i-1][j-1] + 1,当且仅当nums1[i] == nums2[j]时。 同样需要一个result来存放最长子序列长度。

class Solution {
    public int findLength(int[] nums1, int[] nums2) {
        int[][] dp = new int[nums1.length+1][nums2.length + 1];

        int result = 0;

        for(int i=1; i<=nums1.length; i++) {
            for(int j=1; j<=nums2.length; j++) {
                if(nums1[i-1] == nums2[j-1]) {
                    dp[i][j] = dp[i-1][j-1] + 1;
                }

                if(dp[i][j] > result) {
                    result = dp[i][j];
                }
            }
        }

        return result;
    }
}