300. Longest Increasing Subsequence
dp[i]为以i为结尾的最长递增子序列,那么要计算dp[i],需要以j遍历从0到i-1, 在每层循环中:
- 若nums[j] < nums[i], 意味着j元素可以参与构成以i为结尾的子序列,那么dp[i] = max(dp[i], dp[j] + 1)
- 若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;
}
}