最长递增子序列长度--动态规划

题目:长度为n的num数组,求其最长递增子序列
思考:

  • 该数组中元素所构成的所有递增子序列可以穷举为以所有元素结尾的递增子序列。

  • 则求最长递增子序列的长度转化为求以各个元素结尾的递增子序列的最长的长度

  • 以下标i结尾的最长递增子序列长度与以下标为i-1结尾的最长递增子序列长度有关-。
    动态规划求解思路

  • 自底向上穷举

/*
num[]={10,9,2,5,3,7,101,18}
1:以10结尾的序列,其最长递增子序列长度为1;
2、以9结尾的序列,其最长递增子序长度为1;
3、以2结尾的序列,其最长递增子序列长度为1;
4、以5结尾的序列,其最长递增子序列长度为2:
   因为2<5, 所以在以5结尾的序列中,以2结尾的序列可以添加到以5结尾的序列前,又以2结尾的序列,最长递增子序列长度为1,则以5结尾的序列最长递增子序列长度为 1+1=2;
5、以3结尾的序列,其最长递增子序列长度为2:  1+1=2;
6、以7结尾的序列,其最长递增子序列长度为3: 
   因为 2<7, 又以2结尾的最长递增子序列长度为1,故将2添加入当前子序列,其长度为 1+1=2; 5<7,又以5结尾的最长递增子序列长度为2, 则将5加入当前子序列, 其长度为2+1=3; 同理得到将3加入之后最长递增子序列长度为3
......
同理可得各自结尾的最长递增子序列
*/
  • 确定边界(初始化):
    对于数组中任意一个元素结尾的子序列其长度至少为1。

  • 找规律
    假定dp[i]用来表示以i结尾的最长递增子序列的长度,则dp[i]=max(dp[j])+1,(j>=0&&j<i&&num[j]<num[i])
    【以i结尾的所有递增子序列的长度等于i之前,比num[i]小的值结尾的的子序列长度+1,则以i结尾的最长递增子序列长度为其中长度最长的值】

  • 状态转移方程

dp[i]=max(dp[j])+1, for all j, 0<=j<i&&num[j]<num[i]
dp[i]=1 for all j, 0<=j<i&&num[j]>num[i]
  • 代码实现
//num[]={10,9,2,5,3,7,101,18}
public int lengthOfLIS(int[] num){
	//创建一个dp[]数组,用来存储以各个元素结尾的最长递增子序列长度
	int[]dp=new int[num.lenght];
	int maxlenght=0;
	
	
	//计算以各个元素结尾的最长递增子序列长度
	for(int i=0;i<num.lenght;i++){
		//以i结尾的所有子序列中包含自身,且其长度为1
		dp[i]=1; 
		for(int j=0;j<i;j++){
			//以i结尾的其他子序列长度计算
			if(num[j]<num[i]){
				dp[i]=Math.max(dp[j]+1,dp[i]);
			}
		}
		//最大的dp[i]即为最长递增子序列长度
		maxlenght=Math.max(dp[i],naxlength);
	}
	return maxlength;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值