转载原文地址:http://www.cnblogs.com/GodA/p/5180560.html

给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4

说明:

  • 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
  • 你算法的时间复杂度应该为 O(n2) 。

进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

第一种方法:动态规划。

求 2 7 1 5 6 4 3 8 9 的最长上升子序列。我们定义d(i) (i∈[1,n])来表示前i个数以A[i]结尾的最长上升子序列长度。
  前1个数 d(1)=1 子序列为2;
  前2个数 7前面有2小于7 d(2)=d(1)+1=2 子序列为2 7
  前3个数 在1前面没有比1更小的,1自身组成长度为1的子序列 d(3)=1 子序列为1
  前4个数 5前面有2小于5 d(4)=d(1)+1=2 子序列为2 5
  前5个数 6前面有2 5小于6 d(5)=d(4)+1=3 子序列为2 5 6
  前6个数 4前面有2小于4 d(6)=d(1)+1=2 子序列为2 4
  前7个数 3前面有2小于3 d(3)=d(1)+1=2 子序列为2 3
  前8个数 8前面有2 5 6小于8 d(8)=d(5)+1=4 子序列为2 5 6 8
  前9个数 9前面有2 5 6 8小于9 d(9)=d(8)+1=5 子序列为2 5 6 8 9
  d(i)=max{d(1),d(2),……,d(i)} 我们可以看出这9个数的LIS为d(9)=5
  总结一下,d(i)就是找以A[i]结尾的,在A[i]之前的最长上升子序列+1,当A[i]之前没有比A[i]更小的数时,d(i)=1。所有的d(i)里面最大的那个就是最长上升子序列。
public int longestIncreasingSubsequence(int[] nums) {
if(nums.length==0)return 0;
int[] d=new int[nums.length];
int max=0;
for(int i=0;i<nums.length;i++){
d[i]=1; //当nums[i]之前没有比nums[i]更小的数,d[i]=1.每次重新开始计数
for(int j=0;j<i;j++){
if(nums[j]<nums[i]&&(1+d[j]>d[i]))d[i]=1+d[j];//num[j]<num[i]保证了递增的操作,因此只需要不断比较并更新d[i]
}
if(d[i]>max)max=d[i];
}
return max;
}

第二种方法:有以下序列A[]=3 1 2 6 4 5 10 7,求LIS长度。

核心思想是不断的替换,遍历nums数组,通知保证arr数组一定是一个递增的数组(因此可以使用二分法)
如果nums[i]比arr数组最右边的数字还要大,则将Nums[i]直接添加到arr数组的后边,否则nums[i]将会插入到arr[i]
中,使用二分查找法。
这里的二分查找是为了寻找第一个大于num[i]的数字。使用的是upper_bound。
如图所示

 代码如下:

class Solution {
public int lengthOfLIS(int[] nums) {
if(nums.length==0)return 0;
int max=0,next;
int[] arr=new int[nums.length];
arr[0]=nums[0];
for(int i=1;i<nums.length;i++){
next=put(arr,0,max,nums[i]); //从数组中的第二个数开始
arr[next]=nums[i];
if(max<next)max=next;
}
return max+1;
}
//找索引的方法,比如【2,1,4,5,3,6】找到nums[1]的索引为0,nums[2]=4直接添加到arr[2]中,nums[3]=5同理,nums[4]=3会把[1,4,5]中的4替换掉。
public int put(int[] a,int l,int r,int key){
if(a[r]<key)return r+1;
int mid;
while(l<=r){
if(l==r)return l;
mid=l+(r-l)/2;
//返回第一个大于key的索引
if(a[mid]<key)l=mid+1;
else r=mid;
}
return l;
}
}
 

leetcode-最长上升子序列LIS的更多相关文章

  1. 最长回文子序列LCS,最长递增子序列LIS及相互联系

    最长公共子序列LCS Lintcode 77. 最长公共子序列 LCS问题是求两个字符串的最长公共子序列 \[ dp[i][j] = \left\{\begin{matrix} & max(d ...

  2. 2.16 最长递增子序列 LIS

    [本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...

  3. 最长上升子序列LIS(51nod1134)

    1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递 ...

  4. 动态规划(DP),最长递增子序列(LIS)

    题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...

  5. 【部分转载】:【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)、最长下降子序列模版】

    二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound() ...

  6. 题解 最长上升子序列 LIS

    最长上升子序列 LIS Description 给出一个 1 ∼ n (n ≤ 10^5) 的排列 P 求其最长上升子序列长度 Input 第一行一个正整数n,表示序列中整数个数: 第二行是空格隔开的 ...

  7. 一个数组求其最长递增子序列(LIS)

    一个数组求其最长递增子序列(LIS) 例如数组{3, 1, 4, 2, 3, 9, 4, 6}的LIS是{1, 2, 3, 4, 6},长度为5,假设数组长度为N,求数组的LIS的长度, 需要一个额外 ...

  8. 1. 线性DP 300. 最长上升子序列 (LIS)

    最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ...

  9. 最长上升子序列(LIS)模板

    最长递增(上升)子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增(上升)子序列. 考虑两个数a[x ...

  10. hdu1025 dp(最长上升子序列LIS)

    题意:有一些穷国和一些富国分别排在两条直线上,每个穷国和一个富国之间可以建道路,但是路不能交叉,给出每个穷国和富国的联系,求最多能建多少条路 我一开始在想有点像二分图匹配orz,很快就发现,当我把穷国 ...

随机推荐

  1. C#制作ActiveX浏览器插件.net

    开发环境:VS2008 第一步 创建项目 新建一个项目,选择“Windows窗体控件库”,创建一个用户控件项目“ActiveXDemo”(注意,这里起名不能用中文,否则后面会出问题),里面有个用户控件 ...

  2. 第21章 DMA—直接存储区访问

    本章参考资料:<STM32F76xxx参考手册>DMA控制器章节. 学习本章时,配合<STM32F76xxx参考手册>DMA控制器章节一起阅读,效果会更佳,特别是涉及到寄存器说 ...

  3. webapi 获取json数据

    一般的我们可以直接使用参数来接受,这个就不多介绍了 [HttpGet] public IHttpActionResult Test2([FromUri]string name) { object ob ...

  4. DIAView组态软件笔记

    1.为了节省成本,我们往往会在PLC将多个开关量整合到同一个word中,这样关联的变量可以从原有的16个变成现在的一个.这样做带来的麻烦就是需要我们在脚本中自己来解析出数据,通过对2求余(mod 2) ...

  5. 关于content-type请求头的说明

    Content-Type请求头的作用,用于标记请求体数据的格式,如: 1. Content-Type:application/x-www-form-urlencoded 请求体:b'pwd=123&a ...

  6. 点击HTML页面问号出现提示框

    本demo的功能:点击页面按钮在其边缘出现提示信息,点击页面任何一处则消失. 如下图: 1.所需插件: jquery插件: layer插件: 2.HTML内容: ==注意==: class=" ...

  7. CSS技巧之向下箭头

    思路:使用◇符号(可在输入法的软键盘找到该符号),使用定位选择位置,并隐藏溢出的上半部分细点:1.使用i标签的楷体属性把◇变大2.给i只有◇符号一半的高度,并隐藏溢出,正常显示一个向上箭头3.对s使用 ...

  8. Linux系统NBD驱动安装拓展篇

    前言: 最近在安装中标麒麟机器的时候,发现麒麟的操作系统找不到src.rpm包,且系统内部也没有内核文件,导致正常方法安装NBD驱动无法实施.故这里找了另一种办法帮助此类型操作系统安装NBD驱动. 一 ...

  9. linux配置mysq与navicat关联

    第一步:在linux中安装mysql(执行如下语句) 安装 mysql: yum install mysql yum install mysql-server yum install mysql-de ...

  10. python环境Anaconda的安装

    本人最开始的的环境为:win10 + 32位的python 最近想学习一下爬虫,听说某些库需要64的python才能实现(本人也是小白,只是平时喜欢折腾,这里是听说,暂时没有能力解释),无奈之下只好卸 ...