动态规划求解最长递增子序列的长度

简介:

一,问题描述

给定一个序列,求解它的最长 递增 子序列 的长度。比如: arr[] = {3,1,4,1,5,9,2,6,5}   的最长递增子序列长度为4。即为:1,4,5,9

 

二,算法分析

有两种方式来求解,一种是转化为LCS问题。即,首先对数组排序,将排序后的结果存储在辅助数组中。排序时间复杂度O(NlogN),排序后的数组与原数组组成了LCS(N,N)问题。解决LCS问题的时间复杂度为O(N^2),故整个算法的时间复杂度为O(N^2),空间复杂度为O(N)

 

另一种方式是直接用DP求解,算法如下:时间复杂度为O(N^2)

①最优子问题

设lis[i] 表示索引为 [0...i] 上的数组上的 最长递增子序列。初始时,lis[i]=1,注意,在DP中,初始值是很重要的,它是整个算法运行正确的关键而初始值 则可以 通过 画一个小的示例来 确定。

当 arr[i] > arr[j],lis[i] = max{lis[j]}+1 ;其中,j 的取值范围为:0,1...i-1

当 arr[i] < arr[j],lis[i] = max{lis[j]} ;其中,j 的取值范围为:0,1...i-1

 

②重叠子结构

从上面可以看出,计算 lis[i]时,需要计算 lis[j],其中 j < i,这说明有重叠子问题。借用网路中一张图如下:

复制代码
                     lis(4)           
                 /       |      \
         lis(3)      lis(2)    lis(1)  
        /     \        /         
  lis(2)  lis(1)   lis(1) 
  /    
lis(1)
复制代码

而初始值 则可以 通过 画一个小的示例来 确定。

 

参考资料:

求解两个字符串的最长公共子序列

动态规划(3)-最长递增子序列

 

三,代码实现

错误版本1:

复制代码
 1     private static int lis(int[] arr, int length){
 2         int lis[] = new int[length];
 3         
 4         //init
 5         for(int i = 0; i < length; i++)
 6             lis[i] = 1;
 7         
 8         for(int i = 1; i < length; i++)
 9         {
10             for(int j = 0; j < i; j++)
11             {
12                 
13                 if(arr[i] > arr[j])
14                 {
15                     if(lis[j] + 1 > lis[i])
16                         lis[i] = lis[j] + 1;
17                 }
18                 else{
19                     if(lis[j] > lis[i])
20                         lis[i] = lis[j];
21                 }
22             }
23         }
24         return lis[length - 1];
25     }
复制代码

第13行if语句会导致bug,arr[i]要大于 j belongs to  0,1,...i-1 中所有的 arr[j]中的最大值,并且 lis[i] 是该最大值 arr[j] 所对应的 lis[j] +1,而不是某个其他的arr[j] 对应的 lis[j]+1

 

正确完整版本:

复制代码
public class LIS {
    public static int lis(int[] arr){
        if(arr == null || arr.length == 0)
            return 0;
        return lis(arr, arr.length);
    }
    
    private static int lis(int[] arr, int length){
        int lis[] = new int[length];
        
        //init
        for(int i = 0; i < length; i++)
            lis[i] = 1;
        
        for(int i = 1; i < length; i++)
        {
            for(int j = 0; j < i; j++)
            {
//                lis[i]=max{lis[i-1], lis[i-1]+1}
                if(arr[i] > arr[j] && lis[j] + 1 > lis[i])
                    lis[i] = lis[j] + 1;
            }
        }
        
        int max = lis[0];
        for(int i = 1; i < length; i++)
            if(max < lis[i])
                max = lis[i];
        return max;
    }
    
    public static void main(String[] args) {
        int[] arr = {3,1,4,1,5,9,2,6,5};
        int result = lis(arr);
        System.out.println(result);
    }
}本文转自hapjin博客园博客,原文链接:http://www.cnblogs.com/hapjin/p/5597658.html,如需转载请自行联系原作者
复制代码
相关文章
|
8月前
|
机器学习/深度学习 弹性计算 缓存
简单聊聊,阿里云2核2G3M带宽云服务器与轻量应用服务器区别及选择参考
2核2G3M带宽云服务器与轻量应用服务器是目前阿里云的活动中,入门级走量型云服务器,轻量云服务器2核2G3M带宽68元一年,经济型e实例云服务器2核2G3M带宽99元1年。同样的配置,对于有的新手用户来说,有必要了解一下他们之间的区别,以及各自的购买和续费相关政策,从而选择更适合自己需求的云服务器。本文为大家简单分析一下我们应该选择哪一款。
|
11月前
|
监控 数据可视化 数据挖掘
成本累计曲线:项目预算的秘密武器
成本累计曲线(S曲线)是项目管理中用于分析和跟踪成本的重要工具,它随时间展示项目的累计成本或资源使用量,帮助项目经理实时了解成本支出和进度差异,及时调整预算和资源分配。本文详细介绍了S曲线的定义、关键步骤及在项目各阶段的应用,强调了项目管理工具在提高成本管理效率和准确性方面的辅助作用。
354 3
|
存储 数据处理 图形学
什么是帧同步技术?
【5月更文挑战第3天】什么是帧同步技术?
608 9
|
存储 弹性计算 安全
阿里云活动内云服务器没有数据盘怎么办?购买后如何购买并挂载云盘?
在我们通过阿里云的活动来购买云服务器的时候,一般默认情况下只有系统盘,是没有数据盘的,但是很多用户处于实际使用需求和安全等方面的需求,通常都需要在购买之后单独再购买一块云盘作为数据盘挂载到云服务器上,本文以图文形式为大家展示阿里云活动内云服务器购买流程以及购买后如何购买并挂载云盘,适合新手用户参考。
阿里云活动内云服务器没有数据盘怎么办?购买后如何购买并挂载云盘?
|
机器学习/深度学习 人工智能 自然语言处理
AI顶会ICLR 2022 | WPipe 蚂蚁集团大规模 DNN 训练的流水线并行技术
AI顶会ICLR 2022 | WPipe 蚂蚁集团大规模 DNN 训练的流水线并行技术
1011 0
AI顶会ICLR 2022 | WPipe 蚂蚁集团大规模 DNN 训练的流水线并行技术
|
架构师 算法 测试技术
嵌入式系统软件架构设计(长篇深度好文)
嵌入式系统软件架构设计(长篇深度好文)
7836 2
|
机器学习/深度学习 人工智能 自然语言处理
完全开源!快速上手 AI 理论及应用实战来了
完全开源!快速上手 AI 理论及应用实战来了
307 0
完全开源!快速上手 AI 理论及应用实战来了
|
JavaScript 前端开发 Android开发
auto.js下载安装教程
auto.js下载安装教程
995 0
auto.js下载安装教程
|
机器学习/深度学习 人工智能 算法
机器之心独家解读:华为首款手机端AI芯片麒麟970
人工智能的最近一次浪潮起源于 2011 年前后深度学习(Deep Learning)引起的大发展。在其背后,快速发展的 GPU 功不可没。近年来,人们逐渐认识到计算芯片对于人工智能的重要性,围绕 AI 任务进行专有加速的芯片越来越多,但无论是 AlphaGo 背后的谷歌 TPU 还是加入了全新 Tensor Core 结构的英伟达 Tesla V100,这些芯片都是为服务器端进行设计的,在移动端对于机器学习任务加速的 SoC 还未出现。9 月 2 日,在德国柏林举行的 IFA 2017 展会上,华为正式发布了全球首款移动端 AI 芯片麒麟 970,一举填补了这一空白。
827 0
机器之心独家解读:华为首款手机端AI芯片麒麟970
|
5G 索引
带你读《5G 无线增强设计与国际标准》第二章接入增强2.1 2步随机接入(三)
《5G 无线增强设计与国际标准》第二章接入增强2.1 2步随机接入(三)
带你读《5G 无线增强设计与国际标准》第二章接入增强2.1 2步随机接入(三)