最长递增子序列(动态规划实现)
来源:互联网 发布:北京大学域名 编辑:程序博客网 时间:2024/06/05 14:15
题目描述:
(题目来源于牛客网)对于一个数字序列,请设计一个复杂度为O(nlogn)的算法,返回该序列的最长上升子序列的长度,这里的子序列定义为这样一个序列U1,U2...,其中Ui < Ui+1,且A[Ui] < A[Ui+1]。
给定一个数字序列A及序列的长度n,请返回最长上升子序列的长度。
测试样例:
[2,1,4,3,1,5,6],7
返回:4解法:题目要求复杂度为O(nlogn),我们可以这样想,肯定是要遍历数组,这里的复杂度就是O(n),那么我们在每个数那里就最多用到O(logn)的复杂度,其实我思路也挺乱的,直接说做法吧,我们先用一个辅助数组b,(长度为a.length+1,不能用list链表,复杂度会超过要求),b[0]=0(这个没用),b[1] = a[0],length =2,length记录数组b的实际长度,以后b[1]记录长度为1 的有序序列的的最小值,b[2]记录长度为2有序序列的最小值(例如1,3,2)b[2]就记录2,因为长度为2的有序序列有(1,3)和(1,2),依次类推,得来的b数组肯定是非递增有序序列,我们在遍历到a[k]的时候,只需要在b数组中去查找比a[k]大的第一个最小数的,返回其位置,在数组b中若这一位置还是0,说明a[k]是最多的,可以将其置为a[k],若有值,可以将其改为a[k],最后数组b的长度-1就是结果(减一是因为b[0]没有用)package dynamic;public class dynamic2{public static void main(String[] args){// TODO Auto-generated method stubint a[] ={ 2, 1, 4, 3, 1, 5, 6 };int n = 7;int num = da(a, n);System.out.println(num);}// 算法思想,用一个数组,记录最长子序列长度从1到n对应的最小数private static int da(int[] A, int n){// TODO Auto-generated method stubint b[] = new int[8];// b[0]不用,那就刚好,b[1]纪录长度1对应的最小数,b数组必定是一个从小到大的有序序列int length = 1;// 数组b的实际长度,初始化为1b[1] = A[0];length++;for (int i = 1; i < A.length; i++){int num = select(b, 1, length - 1, A[i]);// 查找从1到length-1的值if (b[num] == 0)length++;b[num] = A[i];}return length-1;}// 查找a[i]在b中对应的情况,找到比a[i]小的那个数的最大数,例如b[2]==3,现在查找4,// 那么b[3]=4,最长子序列可以加1private static int select(int[] b, int start, int end, int k){int middle = (start + end) / 2;int i = 0;int num = 0;if (start > middle)return 0;if (b[middle] == k){for (i = middle; i <= end; i++){// 防止连续好多都与k相等,我们取下标最大的那个if (b[i] != k)break;}return i;// 返回那个与k相等的那个数(若有多个,取最大的额那个)的下标} else if (b[middle] > k){num = select(b, start, middle - 1, k);if (num == 0)// 如果比这里面所有的数都大,返回0{return start;// 返回那个与k相等的那个数(若有多个,取最大的额那个)的下标} else{return num;}} else{num = select(b, middle + 1, end, k);if (num == 0)// 如果比这里面所有的数都大,返回0,num==0表示递归要结束,找不到那个要查找的数{return end + 1;// 返回那个与k相等的那个数(若有多个,取最大的额那个)的下标} else{return num;}}}}
阅读全文
0 0
- Java-LIS最长递增子序列(动态规划实现)
- 最长递增子序列(动态规划实现)
- 最长递增子序列(动态规划)
- 最长递增子序列(动态规划)
- 最长递增子序列(动态规划)
- 动态规划:最长单调递增子序列
- 动态规划之最长递增子序列
- 动态规划--最长单调递增子序列
- 动态规划_最长递增子序列
- 动态规划之最长递增子序列
- 【动态规划】单调递增最长子序列
- 动态规划 - 最长递增子序列
- 最长单调递增子序列--动态规划
- 动态规划 最长递增子序列
- 动态规划最长递增子序列问题
- 动态规划求最长递增子序列
- 动态规划 - 最长递增子序列LIS
- 【动态规划】最长递增子序列
- Spring Boot (教程十二: AOP拦截器)
- Java多线程——龟兔赛跑
- java 实现最简单的斐波那契数列
- Windows上Python和Pycharm的安装
- ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数
- 最长递增子序列(动态规划实现)
- Lua table转string函数
- JavaScript 多选框多选与取消多选实例:
- C# DataTable转为对象或对象列表
- 单例模式的七种写法
- 用微信小程序开店之六——小程序组件2:“基础内容”
- 2016年青岛区域赛 Coding Contest(费用流)
- 安卓位运算处理usb,蓝牙等协议接收的数据
- 深入理解半同步复制