思路如下:
1、为了找到上升序列最大值,考虑动态规划。
2、关键是状态转移方程。借下图:
可以得到dp初始化为1,因为每个数字都可以自成一个子序。
两层for循环,每次遍历一个i,就比较当前nums[i]与nums[j]的大小(0=<j<i),如果nums[i]>nums[j],则说明nums[i]与nums[j]可以构成一个子序列,接着对dp[i]进行讨论。
dp[i]表示在[0,i]中以nums[i]为最大值的最长上升子序列,当找到nums[i]>nums[j]对应的j时,比较dp[i]与dp[j]+1(加1表示加上nums[i]构成一个新的长度)的最大值,赋给dp[i]。
每遍历一个i,就更新最大值max。
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums.length==0){
return 0;
}
int m=nums.length;
int[]dp=new int[m];
int max=0;
//dp初始化为1
Arrays.fill(dp,1);
for(int i=0;i<m;i++){
for(int j=0;j<i;j++){
//只有nums[i]>nums[j]时,nums[i]才能构成一个上升序列
if(nums[i]>nums[j]){
//当找到nums[j]<nums[i]的j值时,比较j所在的dp+1与dp[i]最大值,表示以nums[i]为最大值的[0,i]数组所能形成的上升子序列个数
dp[i]=Math.max(dp[i],dp[j]+1);
}
}
//每遍历一次nums[i]更新一个最大值max
max=Math.max(dp[i],max);
}
return max;
}
}
原题地址:
300. 最长上升子序列