Longest Increasing Sequence
public class Longest_Increasing_Subsequence {
/**
* O(N^2)
* DP
* 思路:
* 示例:[1,0,2,4,10,5]
* 找出以上数组的LIS的长度
* 分析:
* 只要求长度,并不要求找出具体的序列
* 问题可以拆分为
* 1. 对于[1],找出LIS
* 2. 对于[1,0],找出LIS
* 3. 对于[1,0,2],找出LIS
* 4. 对于[1,0,2,4],找出LIS
* ...
* 最后,对于[1,0,2,4,10,5],找出LIS
* 再进一步思考,例如:
* 找出[-1,0,1,0,2,4]的LIS,就要找到在4之前符合条件(都比4小且都为升序)的LIS的长度 => [-1,0,1]是满足情况的(最长,都是升序,都比4小)
* 那么就要有一个数据结构来记录到某一个index上,LIS的长度。因为每一个index上的LIS长度并不是固定为前一个加1,所以每一个都要记录下来 => 数组dp[]
* dp[i]记录的是,在i这个index上,LIS的长度
* 比如:
* index 0 1 2 3 4 5
* dp:[ 1,2,3,1,4,5] //dp数组
* ar:[-1,0,1,0,2,4] //原数组
* dp[1] = 2表示在1这个index上,LIS的长度是2([-1,0])
* dp[4] = 4表示在4这个index上,LIS的长度是4([-1,0,1,2])
* ----------------------------
* 状态转换方程:
* dp[i] = dp[k] + 1; (dp[k] = max(dp[0], dp[1], ... dp[i-1])) // dp[i] = 在i以前最大的LIS长度加上1
* 以上方程的成立条件:
* nums[k] < nums[i] //保持递增序列的属性
*/ /**
* O(N^2)
*/
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = 1;
for (int i = 1; i < nums.length; i++) {
int beforeMaxLen = dp[i];
// 在0 ~ i之间比较LIS的长度
for(int j = 0; j < i; j++) {
if (nums[j] < nums[i] && dp[j] > beforeMaxLen) { //注意dp[j] > beforeMaxLen,新的长度要大于之前选出来的长度才能更新
beforeMaxLen = dp[j];
}
}
dp[i] = beforeMaxLen + 1;
}
int max = 0;
// 在数组里找出最大的长度即可
for (int i = 0; i < nums.length; i++) {
if (dp[i] > max){
max = dp[i];
}
}
return max;
} /**
* O(N*logN)
* 思路:
* 满足递增序列,就直接加入list中
* 如果发现有降序出现,找出在原数组中比它大的第一个数的index,然后在list中替换那个数
* 最后返回list的长度
* 原理:
* 因为只求长度,所以没有必要存储确切的sequence
*/
public int lengthOfLIS_2(int[] nums) {
List<Integer> list = new ArrayList<>();
for(int num : nums) {
if(list.isEmpty() || list.get(list.size() - 1) < num) { // 不满足递增序列
list.add(num);
} else {
list.set(findFirstLargeEqual(list, num), num);
}
} return list.size();
} private int findFirstLargeEqual(List<Integer> list, int target)
{
int start = 0;
int end = list.size() - 1;
while(start < end) {
int mid = start + (end - start) / 2;
if(list.get(mid) < target) {
start = mid + 1;
}
else {
end = mid;
}
} return end;
} /**
* 测试用
*/
public static void main(String[] args) {
Longest_Increasing_Subsequence lis = new Longest_Increasing_Subsequence();
int[] a = {-1,0,1,0,2,4};
System.out.print(lis.lengthOfLIS_2(a));
}
}
Longest Increasing Sequence的更多相关文章
- 动态规划 ---- 最长不下降子序列(Longest Increasing Sequence, LIS)
分析: 完整 代码: // 最长不下降子序列 #include <stdio.h> #include <algorithm> using namespace std; ; in ...
- [Leetcode] Binary search, DP--300. Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
- CSUOJ 1551 Longest Increasing Subsequence Again
1551: Longest Increasing Subsequence Again Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 75 Solved ...
- [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...
- [LintCode] Longest Increasing Subsequence 最长递增子序列
Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return ...
- The Longest Increasing Subsequence (LIS)
传送门 The task is to find the length of the longest subsequence in a given array of integers such that ...
- SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治
Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...
- [LeetCode] Binary Tree Longest Consecutive Sequence II 二叉树最长连续序列之二
Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. Especia ...
- 673. Number of Longest Increasing Subsequence
Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...
随机推荐
- Servlet中Service方法
doGet方法只能处理Get方式提交的请求,doPost则可以处理Post方式提交的请求, 一种既可以处理Get方式又可以处理Post方式的提交的请求,它就是Service方法. service方法用 ...
- DAO设计模式 -- 使用数据库连接类连接MySql数据库并实现添加用户
1. DAO简介 DAO设计模式是属于J2EE数据库层的操作,使用DAO设计模式可以简化大量代码,增强程序的可移植性. 2. DAO各部分详解 DAO设计模式包括5个重要的部分,分别为数据 ...
- 8、双向一对多的关联关系(等同于双向多对一。1的一方有对n的一方的集合的引用,同时n的一方有对1的一方的引用)
双向一对多关联关系 “双向一对多关联关系”等同于“双向多对一关联关系”:1的一方有对n的一方的集合的引用,同时n的一方有对1的一方的引用. 还是用客户Customer和订单Order来解释: “一对多 ...
- java对象实例化
JAVA类,只要知道了类名(全名)就可以创建其实例对象,通用的方法是直接使用该类提供的构造方法,如 NewObject o = new NewObject(); NewObject o = new N ...
- SQLserver游标原理和使用方法
在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句.但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录.那么如何解决这种问题呢 ...
- VMware下Ubantu与Windows共享文件夹的方法
刚刚接触linux的同学往往喜欢在windows系统下安装一个虚拟机,然后在虚拟机上进行操作,但是windows和虚拟机上的linux系统之间的文件互传往往不太方便,今天就总结一个小技巧在window ...
- 函数 page_dir_get_n_heap
查看某page中含有的记录个数 #define PAGE_N_HEAP 4 /* number of records in the heap, bit =flag: new-style compact ...
- java---面试题---.java"源文件中可以包括多个类(不是内部类)
答题时,先答是什么,再答有什么作用和要注意什么 一个".java"源文件中可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致,main方法只能写在 ...
- Qt之进程间通信(QProcess)
简述 QProcess可以在应用程序内部与其它进程通信,或启动其它应用程序.与在终端机之类的命令输入窗口上使用名称和参数是一样的,可以使用QProcess提供的函数start()启动进程.可以注册QS ...
- Qt 多线程学习
最近的项目上用到了关于多线程的知识,自己也比较感兴趣,所以就拿了那本<C++ GUI Qt4 编程>来学习. 这本书的第14章是关于多线程的知识,使用的Qt版本是Qt4.x.在下用的是最新 ...