300.最长递增子序列
思路:
dp[i]表示以i位置结尾的最长递增子序列,如果i位置的数有比其前面位置的数大,位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。
代码:
class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
if(n == 1) return 1;
int[] dp = new int[n];
Arrays.fill(dp,1);
int res = 1;
for(int i = 1; i < n; 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;
}
}
需要注意的点:
初始化时各位置都为1
674. 最长连续递增序列
思路:
代码:
class Solution {
public int findLengthOfLCIS(int[] nums) {
int n = nums.length;
if(n == 1) return 1;
int[] dp = new int[n];
Arrays.fill(dp,1);
int res = 1;
for(int i = 1; i < n; i++){
if(nums[i] > nums[i - 1]){
dp[i] = dp[i - 1] + 1;
}
if(dp[i] > res) res = dp[i];
}
return res;
}
}
需要注意的点:
跟上一题一样,要记录dp[i]中的最大值,并将其作为结果、
718. 最长重复子数组
思路:
代码:
class Solution {
public int findLength(int[] nums1, int[] nums2) {
//dp[i][j]含义:nums1以i-1结尾和nums2以j-1结尾最长重复的子数组
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
int res = 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] > res) res = dp[i][j];
}
}
return res;
}
}
需要注意的点:
子数组就是连续数组
dp数组从(1,1)开始有意义是为了初始化方便,相应地,dp数组的大小也要调整(长和宽都要为数组尺寸+1)。