最长上升子序列(Longest increasing subsequence)
问题描述
对于一串数A={a1a2a3…an},它的子序列为S={s1s2s3…sn},满足{s1<s2<s3<…<sm}。求A的最长子序列的长度。
动态规划法
算法描述:
设数串的长度为n,L[i]为以第i个数为末尾的最长上升子序列的长度,a[i]为数串的第i个数。
L[i]的计算方法为:从前i-1个数中找出满足a[j]<a[i](1<=j<i)条件的最大的L[j],L[i]等于L[j]+1。
动态规划表达式:
代码实现:
int LIS(int a[], int n)
{
int len[MAXSIZE];
int i, j;
int maxlen = ;
//计算以第i个数为结尾的最长上升子序列的长度
for (i = ; i <= n; i++)
{
len[i] = ;
//从前i-1个数中找出满足a[j]<a[i](1<=j<i)条件的最大的L[j]
for (j = i-; j >= ; j--)
{
if (a[j] < a[i] && len[j] > len[i])
{
len[i] = len[j];
}
}
len[i]++; if (len[i] > maxlen)
{
maxlen = len[i];
}
}
return maxlen;
}
上述算法的时间复杂度为O(n2)。
改进算法:
在从前i-1个数中找出满足a[j]<a[i](1<=j<i)条件的最大的L[j]的时间复杂度为O(n),这里采用二分查找的方法对它进行优化,使其复杂度降为O(nlogn)。
增设一个m[]数组,m[x]存放长度为x的最长上升子序列的最小末尾数。例:m[3] = 17表示长度为3的最长上升子序列的最小末尾数为17。
由于子序列是上升的,所以m数组中的元素有一个性质,当x<y时,m[x]<m[y],利用这个性质来使用二分查找。
设m数组所存储的最长上升子序列的长度为k,当前计算的数为第i个
如果a[i]>m[k],则m[++k]=a[i];
否则在m[1~k]内二分查找小于(等于)a[i]的最大值的位置p,m[p]=a[i]。
代码实现:
int BSearch(int a[], int n, int t)
{
int low = ;
int high = n; while (low <= high)
{
int mid = (low + high) / ;
if (t == a[mid])
{
return mid;
}
else if (t > a[mid])
{
low = mid + ;
}
else
{
high = mid - ;
}
}
return low;
} int LIS_BSearch(int a[], int m[], int n)
{
int maxlen = ; //最长上升子序列的长度
m[maxlen] = a[]; int i;
for (i = ; i <= n; i++)
{
if (a[i] > m[maxlen])
{
m[++maxlen] = a[i];
}
else
{
//返回小于a[i]的最大值的位置p
int p = BSearch(m, maxlen, a[i]);
m[p] = a[i];
}
}
return maxlen;
}
改进后的算法时间复杂度为O(nlogn)。
最长上升子序列(Longest increasing subsequence)的更多相关文章
- [Swift]LeetCode300. 最长上升子序列 | Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...
- 300最长上升子序列 · Longest Increasing Subsequence
[抄题]: 往上走台阶 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的. 样例 给出 [5,4,1,2,3],LIS 是 [1,2 ...
- nlog(n)解动态规划--最长上升子序列(Longest increasing subsequence)
最长上升子序列LIS问题属于动态规划的初级问题,用纯动态规划的方法来求解的时间复杂度是O(n^2).但是如果加上二叉搜索的方法,那么时间复杂度可以降到nlog(n). 具体分析参考:http://b ...
- 动态规划--最长上升子序列(Longest increasing subsequence)
前面写了最长公共子序列的问题.然后再加上自身对动态规划的理解,真到简单的DP问题很快就解决了.其实只要理解了动态规划的本质,那么再有针对性的去做这方的题目,思路很快就会有了.不错不错~加油 题目描述: ...
- 最长递增子序列(Longest increasing subsequence)
问题定义: 给定一个长度为N的数组A,找出一个最长的单调递增子序列(不要求连续). 这道题共3种解法. 1. 动态规划 动态规划的核心是状态的定义和状态转移方程.定义lis(i),表示前i个数中以A[ ...
- 【转】动态规划:最长递增子序列Longest Increasing Subsequence
转自:https://www.cnblogs.com/coffy/p/5878915.html 设f(i)表示L中以ai为末元素的最长递增子序列的长度.则有如下的递推方程: 这个递推方程的意思是,在求 ...
- 算法实践--最长递增子序列(Longest Increasing Subsquence)
什么是最长递增子序列(Longest Increasing Subsquence) 对于一个序列{3, 2, 6, 4, 5, 1},它包含很多递增子序列{3, 6}, {2,6}, {2, 4, 5 ...
- [Swift]LeetCode594. 最长和谐子序列 | Longest Harmonious Subsequence
We define a harmonious array is an array where the difference between its maximum value and its mini ...
- 最长递增子序列(Longest Increase Subsequence)
问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱).例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8 ...
- 最长公共子序列(Longest common subsequence)
问题描述: 给定两个序列 X=<x1, x2, ..., xm>, Y<y1, y2, ..., yn>,求X和Y长度最长的公共子序列.(子序列中的字符不要求连续) 这道题可以 ...
随机推荐
- sql把一段时间分割成周,月,季度,年的时间段
--本周 select TO_CHAR(CREATE_DATE ,'yyyy-MM-dd')as NEW_DATE , TO_CHAR(trunc(CREATE_DATE, ,'yyyy-MM-dd' ...
- 使用IDEA集成Spring框架时右下角警戒
反正看到报错就不爽,就要去解决它 这个警戒的意思大概就是: spring配置检查 找到未映射的Spring配置文件. 请配置Spring的Facet. 那这玩意怎么配置? 点击IDEA右上角的Proj ...
- MIL/SIL/PIL/HIL/VIL
MIL:Model in the loop 模型在环,对模型在模型的开发环境下(如SIMULINK)进行仿真,通过输入一系列的测试用例,验证模型是否满足设计的功能需求.验证控制算法模型是否准确地实现了 ...
- 利用ExpandableListView实现常用号码查询功能的实现
package com.loaderman.expandablelistviewdemo; import android.content.Context; import android.databas ...
- Appium移动自动化测试(二)之appuim + 夜神模拟器
环境搭建起来之后, 就可以开始移动自动化了. 但是使用自带的AVD开启模拟器, 速度实在太慢. 于是用夜神来做替代, 稍微能够有一些提速. 启动appuim 打开Appium,点击右上角Start按钮 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_2_01传统架构演进到分布式架构
笔记 第二章 架构演进和分布式系统基础知识 1.传统架构演进到分布式架构 简介:讲解单机应用和分布式应用架构演进基础知识 (画图) 高可用 LVS+keepalive :负载均衡的知识点 1. ...
- stringstream 类型转换
stringstream可以吞下不同的类型,然后吐出不同的类型. 这样可以实现int,string,double等类型的转换 #include<sstream> using namespa ...
- kubernetes系列:(三)、helm的安装和使用
一.helm简介 kubernetes : 解决了容器维护的难题,通过yaml编写,比如deployment,job,statefulset.configmap等等,通过控制循环,让容器镜像便于管理, ...
- kubernetes学习:CKA考试题
1. 列出环境内所有的pv 并以 name字段排序(使用kubectl自带排序功能) kubectl get pv --sort-by=.metadata.name 2. 列出指定pod的日志中状态为 ...
- linux 基础 文件操作
cat -A /etc/passwdnl -ba passwd cat -A man_db.conf more man_db.conf less man_db.conf head -n 5 /var/ ...