算法心得1:由$nlogn$复杂度的LIS算法引起的思考
LIS(Longest Increasing Subsequence)是一类典型的动态规划类问题,简化描述如下:
给定$N(n) = \{1,2...,n\}$的一个排列$P(n)$,求$P(n)$中最长上升子列的长度。
譬如令$n = 6$, $N(6) = \{1,2,3,4,5,6\}$,$P(n) = \{1,4,2,5,3,6\}$。
容易发现$LIS(P(n)) = \{1,2,3,6\} or \{1,4,5,6\}...$。
起初我们拿到问题的思路是这样的,我们试着先分析序列的前缀,考虑P(n)中前k项的LIS,即试图分析$LIS(P(k)), k <= n$,
记$P(n) = A$,考虑由$k->k+1$的递推,若$A(k+1) > A(k)$,我们显然有$LIS(P(k+1)) = 1 + LIS(P(k))$,但若$A(k+1) < A(k)$,
则有$A(k+1) = max{LIS(P(i))} + 1, (A(i) < A(k+1), i <= k)$,那么这样做的复杂度为$O(n)$,求$LIS(P(n))$的复杂度为$O(n^2)$。
能不能更快点呢,我们的计算是否有冗余呢?我们知道答案是肯定的。
比如我们在检查到A(k)项时希望知道所有已经检查过的项对应的LIS的最大值,这样我们取其值加一即可得$LIS(P(k))$。
我们试图维护这样的一个数据结构,以线段树为例,我们构建一颗覆盖区间$[1...n]$的线段树,所有叶子结点value值初始化为$-∞$。
假设在检查$A(k)$之间线段树上储存了之前所有已访问过的项计算LIS时的信息,那么在计算$LIS(P(k))$时,我们取$[1,...A(k) - 1]$区间的最大值,
那么有区间内未访问项的值仍未$-∞$,已访问项的最大值即为所取,我们将其加一得到$LIS(P(k))$,为了维护该结构,将叶子结点A(k)对应的值更新为$LIS(P(k))$,
每次操作的复杂度为$O(logn)$,总复杂度为$O(nlogn)$。
虽然复杂度降低了,但是我们觉得使用线段树解决这个问题可能并非必要,能不能用更简单的方法实现同样复杂度的算法?
或者说,我们之前$O(n^2)$算法其使用的数据结构有何改进之处,如何重新组织信息才能使其更有利于解题?
------------------------------------------------------------
注意到我们之前关心的是项所对应位置,然后根据其位置查找其LIS并更新答案,实际上我们关心的只是满足$A(i) < A(k)$对应的最大LIS值,然而我们需要认识到
的是$A(k)$是在不断变化的,然而右边LIS的值则是便于处理的,并且具有单调可更新性。这就是问题解决的入口。
考虑固定LIS值,储存LIS值等于它的最小项,那么在检查A(k)时,只需用二分查找便可求得可以最为当前项前导项对应的LIS最大值,其后再对该序列用当前LIS更新即可。
时间复杂度为$O(nlogn)$,空间复杂度为$O(n)$。
高效的算法需要对原始数据加以更充分的利用,使之更容易呈现出实际问题的本质,使子问题更加主动地成为整个个问题解决的关键有效部分。
算法心得1:由$nlogn$复杂度的LIS算法引起的思考的更多相关文章
- 4. 文本相似度计算-CNN-DSSM算法
1. 文本相似度计算-文本向量化 2. 文本相似度计算-距离的度量 3. 文本相似度计算-DSSM算法 4. 文本相似度计算-CNN-DSSM算法 1. 前言 之前介绍了DSSM算法,它主要是用了DN ...
- 3. 文本相似度计算-DSSM算法
1. 文本相似度计算-文本向量化 2. 文本相似度计算-距离的度量 3. 文本相似度计算-DSSM算法 4. 文本相似度计算-CNN-DSSM算法 1. 前言 最近在学习文本相似度的计算,前面两篇文章 ...
- 《数据结构与算法之美》 <01>复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?
我们都知道,数据结构和算法本身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更省存储空间.所以,执行效率是算法一个非常重要的考量指标. 那如何来衡量你编写的算法代码的执行效率呢?这里 ...
- 编程之法:面试和算法心得(寻找最小的k个数)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入n个整数,输出其中最小的k个. 分析与解法 解法一 要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个 ...
- 编程之法:面试和算法心得(字符串包含java实现)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都 ...
- 编程之法:面试和算法心得(旋转字符串java实现)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b ...
- 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法
转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...
- 算法与设计模式系列1之Python实现常见算法
preface 常见的算法包括: 递归算法 二分法查找算法 冒泡算法 插入排序 快速排序 二叉树排序 下面就开始挨个挨个的说说原理,然后用Python去实现: 递归算法 一个函数(或者程序)直接或者间 ...
- Java常用排序算法+程序员必须掌握的8大排序算法
概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...
随机推荐
- 操作系统:进程管理和IO控制
一.进程管理 进程管理包括进程控制,进程调度,进程同步与通信,死锁控制四个内容. (一)进程控制 进程是操作系统中运行的基本单位,包括程序段,数据段和进程控制段.操作系统通过进程控制块(PCB)管理进 ...
- Java5、Java6、Java7的新特性
Java5 Java 5添加了8个语言特性:泛型,类型安全枚举,注解,自动装箱和拆箱,增强的循环,静态导入,可变参数,协变返回类型. 1.泛型 Generics: 引用泛型之后,允许指定集合里元素的类 ...
- segger 烧写superboot
选择友善之臂的superboot ,然后才能运行minitool工具进行下载系统,boot->kernel->root nand flash 启动方式,minitool烧写 bootl ...
- .NET: WPF Template
Data Template: 要做一个listBox,里面有车子的简单信息,点了里面的item后就会显示详细信息. car class: using System; using System.Coll ...
- url组成部分
协议 eg:http 主机IP地址 eg :端口号8080 项目资源地址 eg:目录名,文件夹名
- mysql explain
我们使用EXPLAIN解析SQL执行计划时,如果有下面几种情况,就需要特别关注下了: 首先看下 type 这列的结果,如果有类型是 ALL 时,表示预计会进行全表扫描(full table scan) ...
- paper 73 :HDR(High Dynamic Range Imaging)在摄影中指高动态范围成像
HDR(High Dynamic Range Imaging)在摄影中指高动态范围成像.国内的教程基本语焉不详,找到一篇比较详尽的国外教程翻译出来,希望对大家有帮助.^_^ 原文地址:http://p ...
- .scss写法及如何转化为.css
scss可视化工具:http://koala-app.com/index-zh.html scss讲解地址:http://www.cnblogs.com/adine/archive/2012/12/1 ...
- js 默认选中select 选项
<select id="HDname" style="width: 150px;"><option value="0"&g ...
- xUtils之ViewUtil
要使用xutils,首先要导入xutils类库. 其次要添加权限: <uses-permission android:name="android.permission.WRITE_EX ...