最长递增子序列
2015-12-02 16:16
351 查看
求一个一维数组中的最长递增子序列的长度
比如,在序列{1, -1, 2, -3, 4, -5, 6, -7}中,其最长的递增子序列为1,2,4,6
思路: 编程之美上的题,也是蛮经典的动态规划题。 思路还是去找规律,我们拿LCS来表示最长递增子序列的长度
第一个数1, 则LCS(1)=1, 因为就一个数嘛
第二个数-1, LCS(1,-1)=1, 因为-1对于1来说不是递增的
第三个数2, LCS(1,-1,2)=2, 因为2对于前两个数是递增的
所以规律是 LCS(i) = if a[i] > a[0...i-1] => max(1, LCS(1...i-1)) + 1 就是如果a[i]的值大于数组下标在0到i-1之间的全部数, 且max(1, LCS(1...i-1))+1>LCS(i)
上述的方法需要嵌套内循环,当遍历到a[i]元素时,需要对0到i-1之间的元素,依次判断是否小于当前a[i]元素,并且找出最大的LCS值,将其加一付给LCS[i], 时间复杂度是o(n^2)
为了降低时间复杂度,编程之美上的解决方法是对i之前的元素进行快速排序,这样就不用每次都去遍历他们,我的想法是,可以增加一个数组max,max[i-1]保存的是从0到i-1之间遇到的最大元素,数组LCS, LCS[i]保存0到i之间的最大值, 这样每次只需比较a[i]与max[i-1]即可, 如果a[i]>max[i-1] 则max[i]=a[i]然后再去判断LCS的值,否则LCS[i]沿用LCS[i-1], max[i]沿用max[i-1]
这样时间复杂度将为o(n), 用空间换时间了
比如,在序列{1, -1, 2, -3, 4, -5, 6, -7}中,其最长的递增子序列为1,2,4,6
思路: 编程之美上的题,也是蛮经典的动态规划题。 思路还是去找规律,我们拿LCS来表示最长递增子序列的长度
第一个数1, 则LCS(1)=1, 因为就一个数嘛
第二个数-1, LCS(1,-1)=1, 因为-1对于1来说不是递增的
第三个数2, LCS(1,-1,2)=2, 因为2对于前两个数是递增的
所以规律是 LCS(i) = if a[i] > a[0...i-1] => max(1, LCS(1...i-1)) + 1 就是如果a[i]的值大于数组下标在0到i-1之间的全部数, 且max(1, LCS(1...i-1))+1>LCS(i)
void findLCS01(int[] array){ int len = array.length; int[] LIS = new int[len]; for(int i = 0; i < len; i++){ LIS[i] = 1; for(int j = 0; j<i; j++){ if(array[i] > array[j] && LIS[j] + 1 > LIS[i]){ LIS[i] = LIS[j] + 1; } } } show(LIS); }
上述的方法需要嵌套内循环,当遍历到a[i]元素时,需要对0到i-1之间的元素,依次判断是否小于当前a[i]元素,并且找出最大的LCS值,将其加一付给LCS[i], 时间复杂度是o(n^2)
为了降低时间复杂度,编程之美上的解决方法是对i之前的元素进行快速排序,这样就不用每次都去遍历他们,我的想法是,可以增加一个数组max,max[i-1]保存的是从0到i-1之间遇到的最大元素,数组LCS, LCS[i]保存0到i之间的最大值, 这样每次只需比较a[i]与max[i-1]即可, 如果a[i]>max[i-1] 则max[i]=a[i]然后再去判断LCS的值,否则LCS[i]沿用LCS[i-1], max[i]沿用max[i-1]
void findLCS02(int[] array){ int len = array.length; if(len <= 0) return; if(len <= 1) return; int[] LCS = new int[len]; int[] max = new int[len]; LCS[0] = 1; max[0] = array[0]; for(int i = 1; i < len; i++){ LCS[i] = 1; if(array[i] > max[i-1]){ max[i] = array[i]; if(LCS[i-1] + 1 > LCS[i]){ LCS[i] = LCS[i-1] + 1; } }else{ LCS[i] = LCS[i-1]; max[i] = max[i-1]; } } show(LCS); }
这样时间复杂度将为o(n), 用空间换时间了
相关文章推荐
- Apache CXF实现Web Service(3)——Tomcat容器和不借助Spring的普通Servlet实现JAX-RS(RESTful) web service
- C语言宏的特殊用法和几个坑
- [Javascript Data Structures] 队列: 击鼓传花
- 我对自己的选择没有后悔、没有失望—兄弟会
- Linux个人常用命令
- D3.js--入门
- LINUX C语言 DNS
- block strong
- 【android】listView的item失去焦点不能点击
- 怎样写基于GPIO子系统的外接传感器的驱动
- Axure编辑函数大全
- 1043. Is It a Binary Search Tree
- 将android studio项目转换成eclipse
- Sublime Text 2 设置文件详解
- 挤点时间写博客-php&MySQL实践
- ELK 集中日志分析 windows部署实战
- oracle user locke
- 防止网页被iframe嵌入的代码
- java多线程
- iOS某操作霸占主线程过久导致界面假死的一种解决方法