7.子序列(不连续)或子串(连续)
300.最长递增子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1: 输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4
class Solution {
public int lengthOfLIS(int[] nums) {
return process(nums);
}
private int process(int[] nums){
//dp[i]表示i之前包括i的最长上升子序列的长度。
//位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值
int n=nums.length;
int[] dp=new int[n];
Arrays.fill(dp,1);
int res=0;
for(int i=0;inums[j]){
dp[i]=Math.max(dp[i],dp[j]+1);
}
}
res=Math.max(res,dp[i]);
}
return res;
}
}
674. 最长连续递增序列
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。
示例 1: 输入:nums = [1,3,5,4,7] 输出:3 解释:最长连续递增序列是 [1,3,5], 长度为3。 尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。
class Solution {
public int findLengthOfLCIS(int[] nums) {
return process(nums);
}
private int process(int[] nums){
//dp[i] 0....i 连续递增的子序列长度
//dp[i]: nums[i]>nums[i-1] dp[i-1]+1. or 1. max
//init fill 1
int n=nums.length;
int[] dp=new int[n];
Arrays.fill(dp,1);
int res=1;
for(int i=1;inums[i-1]){
dp[i]=dp[i-1]+1;
}
res=Math.max(res,dp[i]);
}
return res;
}
}
718. 最长重复子数组
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
示例:
输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出:3 解释: 长度最长的公共子数组是 [3, 2, 1] 。
class Solution {
public int findLength(int[] nums1, int[] nums2) {
return process(nums1,nums2);
}
private int process(int[] nums1,int[] nums2){
//dp[i][j] nums1 0...i,nums2 0....j 最长的公共子数组长度
//dp[i][j]---> only one choose nums[i]==nums[j]. dp[i-1][j-1]+1
//init 0
int n=nums1.length;
int m=nums2.length;
int[][] dp=new int[n+1][m+1];
int res=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(nums1[i-1]==nums2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}
res=Math.max(res,dp[i][j]);
}
}
return res;
}
}
53. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例: 输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
class Solution {
public int maxSubArray(int[] nums) {
return process(nums);
}
private int process(int[] nums){
//dp[i] 0...i 包括下标i之前的最大连续子序列和为dp[i]
//dp[i]-->dp[i-1]+nums[i],nums[i]. max
//res max(res,dp[i])
//init nums[0]
int n=nums.length;
int[] dp=new int[n];
dp[0]=nums[0];
int res=nums[0];
for(int i=1;i