状态定义
:dp[i]的值代表nums前i个数字定位最长上升子序列长度,转移方程:设j在[0,i)是,考虑每轮计算最新dp[i]时,遍历[0,i)列表区间,做以下判断: 1、nums[i]>nums[j]
时:nums[i]可以接在nums[j]之后,此情况下最长上升子序列长度为dp[j]+1
,2、nums[i]<=nums[j]时:nums[i]无法接在nums[j]之后,此情况上升最序列不成立,跳过;上述所有1情况下,计算出dp[j]+1的最大值,为直到i的最长上升子序列(即dp[i[)dp[i]=max(dp[i[,dp[j]+1) if(nums[i]>nums[j]
package BDyNamicProgramming;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/4/22 0022 14:15
*/
public class Problem300 {
/**
* dp[i]为到i之间的最长上升序列的长度
* 则dp[i-1]为到i-1之间的最长序列子长度
*
* dp[0]=1
* dp[1]= 假如nums[1]>nums[0] 为2 否则为1
*
* dp[i]= 可能为dp[i-1] 也可能为 dp[0],dp[1].//dp[i-1]+1
*
* I所在的元素大于i-1所在元素则为dp[i-1]+1
* 因此可以使用list保存最长上升子序列
*
* 状态定义:
* dp[i]的值代表nums前i个数字的最长上升子序列长度
*
* 转移方程:
* 设j在[0,i)是,考虑每轮计算最新dp[i]时,遍历[0,i)列表区间,做以下判断:
*
* 1、nums[i]>nums[j]时:nums[i]可以接在nums[j]之后,此情况下最长上升子序列长度为dp[j]+1
*
* 2、nums[i]<=nums[j]时:nums[i]无法接在nums[j]之后,此情况上升最序列不成立,跳过
*
* 上述所有1情况下,计算出dp[j]+1的最大值,为直到i的最长上升子序列(即dp[i[)
* 实现方式为遍历j时,每轮执行
* dp[i]=max(dp[i[,dp[j]+1)
* 状态转移方程:dp[i]=max(dp[i[,dp[i]+1)
*
* 返回值:返回dp列表最大值,即可得到全局最长上升子序列长度
*
* @param nums
* @return
*/
public int lengthOfLIS(int[] nums) {
if(nums.length==0) return 0;
if(nums.length==1) return 1;
int[] dp = new int[nums.length];
dp[0]=1;
if(nums[1]>nums[0])
dp[1]=2;
else dp[1]=1;
//求每个dp[i]
for(int i=2;i<nums.length;i++) {
int max = 0;
//对于dp[i]之前的每个dp[j]若
//nums[i]>nums[j] 则在dp[j]的基础上加1,
//求最大的dp[j]即可
for (int j = 0; j < i; j++) {
if (nums[i] >nums[j]) {
max = Math.max(max, dp[j]);
}
}
dp[i] = max + 1;
}
return dp[nums.length-1];
}
public static void main(String[] args) {
int[] arr = {10,9,2,5,3,7,101,18};
Problem300 problem300 = new Problem300();
int size = problem300.lengthOfLIS(arr);
System.out.println(size);
}
}