最长不下降子序列
2015-09-20 16:21
176 查看
package dp; import java.util.Arrays; /*** * [3,4,7,1,9] 的最长不减序列是[3,4,7,9]。返回4。 * * @author MiXian * */ public class LongestNoDecreaseSubArray { /** * O(n^2) */ public static int length(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int l = nums.length; int[] dp = new int[l]; int max = 1; Arrays.fill(dp, 1); for (int i = 1; i < l; ++i) { int n = nums[i]; for (int j = i - 1; j >= 0; --j) { if (nums[j] <= n && dp[j] >= dp[i]) { dp[i] = dp[j] + 1; if (dp[i] > max) { max = dp[i]; } } } } return max; } /** * O(nlogn)的算法关键是它建立了一个数组b[],b[i]表示长度为i的不下降序列中结尾元素的最小值 * K表示数组目前的长度,算法完成后K的值即为最长不下降子序列的长度。 * * 具体点来讲: * * 设当前的以求出的长度为K,则判断a[i]和b[k]: * * 1.如果a[i]>=b[k],即a[i]大于长度为K的序列中的最后一个元素,这样就可以使序列的长度增加1,即K=K+1, * 然后现在的b[k]=a[i] * * 2.如果a[i]<b[k],那么就在b[1]...b[k]中找到最大的j,使得b[j]<a[i],然后因为b[j]<a[i], * 所以a[i]大于长度为j的序列的最后一个元素,那么就可以更新长度为j+1的序列的最后一个元素,即b[j+1]=a[i]。 * * 算法复杂度的分析: * * 因为共有n个元素要进行计算;每次计算又要查找n次,所以复杂度是O(n^2),但是,注意到b[]数组里的元素的单调递增的,所以我们可以用二分法, * 查找变成了logn次. * 这样算法的复杂度就变成了O(nlogn)。 */ public static int len(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int l = nums.length; int[] lastOfLen = new int[l]; int curLen = 0; lastOfLen[0] = nums[0];// 长度为1寸在lastOfLen[0]中 for (int i = 1; i < l; ++i) { if (nums[i] >= lastOfLen[curLen]) { lastOfLen[++curLen] = nums[i]; } else { if (nums[i] < lastOfLen[0]) { lastOfLen[0] = nums[i]; } else { lastOfLen[findLen(lastOfLen, 0, curLen, nums[i])] = nums[i]; } } } return 1 + curLen; } // 将n应该更新的下面返回 n属于[lens[0], lens[r]) private static int findLen(int[] lens, int l, int r, int n) { while (l < r) { int m = (l + r) >> 1; if (n >= lens[m] && n < lens[m + 1]) { return m + 1; } else if (n < lens[m]) { r = m; } else { l = m + 1; } } return l; } public static void main(String[] args) { System.out.println(length(new int[] { 3, 4, 7, 9 })); System.out.println(length(new int[] { 3, 4, 1, 7, 9 })); System.out.println(length(new int[] { 3, 4, 8, 7, 9 })); System.out.println(length(new int[] { 3, 1, 7, 9 })); System.out.println(length(new int[] { 3 })); System.out.println(length(new int[] { 3, 2, 2, 1 })); System.out.println(length(new int[] { 1, 1, 2 })); System.out.println(len(new int[] { 3, 4, 7, 9 })); System.out.println(len(new int[] { 3, 4, 1, 7, 9 })); System.out.println(len(new int[] { 3, 4, 8, 7, 9 })); System.out.println(len(new int[] { 3, 1, 7, 9 })); System.out.println(len(new int[] { 3 })); System.out.println(len(new int[] { 3, 2, 2, 1 })); System.out.println(len(new int[] { 1, 1, 2 })); boolean isTest = true; if (isTest) { int[] lens1 = { 3, 4, 9 }; test(lens1, 3); test(lens1, 4); test(lens1, 5); int[] lens3 = { 1, 5 }; test(lens3, 4); test(lens3, 1); } } // /////////////////// tests private static void test(int[] lens, int n) { for (int i = 0; i < lens.length; ++i) { System.out.print(lens[i] + " "); } System.out.println(" : " + n); System.out.println(findLen(lens, 0, lens.length - 1, n)); } }
相关文章推荐
- cocos3.8屏幕截图
- 在链表中插入节点时候的一个trick
- ObjectAnimator详解(测试用,承接Android动画操作中的测试)
- MYSQL数据库学习----插入、更新、删除
- xcode更新之后插件失效的解决办法
- 友盟推送简单调用
- 1.5环境变量与文件查找(学习过程)
- uCOS-II移植
- 浅析Android-ViewPagerIndicator
- Crisis of HDU 2110 (母函数)
- 2015年9月20日工作日志-----------赵鑫
- 0909 初识编译原理
- [fiddler]目标计算机积极拒绝
- [LeetCode] Majority Element II
- DNS域名解析
- 简要解析XMPP框架及iOS-Objective-C的使用
- GoogleMap(其一)
- linux学习与实战:https://www.shiyanlou.com (不需要你有linux机子, 也不需要安装linux虚拟机)
- Memcached学习笔记
- 关于这学期的一个小小的项目