求LIS的两种方法:DP 与 二分法 ~~

本文详细介绍了求解最长上升子序列(LIS)的两种方法:动态规划(DP)和二分法。对于动态规划,针对严格递增和非降子序列的情况分别给出了时间复杂度为O(N^2)的解决方案。二分法通过维护一个长度为len的数组d,结合下界和上界函数,实现了时间复杂度为O(N*logN)的高效求解。
摘要由CSDN通过智能技术生成

LIS(Longest Increasing Subsequence):最长上升子序列

这里分两种情况来看:

  1. 子序列严格递增(即子序列中不能存在相等)
  2. 子序列非降(即子序列中可以存在相等)

对于序列:a[1] , a[2] , a[3] , … , a[N]


一、动态规划(DP)   时间复杂度:O(N2)

  1. 子序列严格递增:dp[i] = max{1 , dp[j]+1}   ( j<i && a[j]<a[i] )
  2. 子序列非降:dp[i] = max{1 , dp[j]+1}   ( j<i && a[j]<=a[i] )

即找到能衔接在a[i]前最大的dp[j] (a[j]能衔接在a[i]之前)




二、二分法   时间复杂度:O(N*logN)

创建一个数组d(下标从1开始): 维护LIS的长度

一个变量len: 表示当前d的长度,d[len]正好是LIS的末尾元素,最终得到的len即为答案。

初始令 d[1]=a[1],len=1; 再从i=2开始遍历a

注意,数组d中仅仅只是长度与LIS相同,本身并不是一个LIS(因为插入后前后顺序被打乱了),只能得到LIS的长度,若要得到LIS,还需要记录路径。
详见—> https://blog.csdn.net/Ratina/article/details/98875528

1. 子序列严格递增

d[len] < a[i]:说明a[i]能接在d[len]后面,长度增加,直接 d[++len] = a[i];

否则,找到 d(LIS)中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值