标签:return code 完整 [] max war 注意 problem strong
https://leetcode.com/problems/longest-increasing-subsequence/#/solutions
http://www.cnblogs.com/grandyang/p/4938187.html
http://www.cnblogs.com/EdwardLiu/p/5084553.html
先从 O(n^2) 的 DP 做法说起。先从这个开做,是因为 O(n^2) 做
法的普适性高,而且可以无视维度,易于扩展到各种变形与
follow-up 上。
需要返回具体 LIS sequence 的时候,加一个新 array,记录
parent index 一路追踪就可以了~ 和 Largest Divisible Subset
一样。
public class Solution {
public int lengthOfLIS(int[] nums) {
if (nums==null || nums.length==0) return 0;
int res = 1;
int len = nums.length;
int[] dp = new int[len];
Arrays.fill(dp, 1);
for (int i=1; i<len; i++) {
for (int j=0; j<i; j++) {
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[i], dp[j]+1);
if (dp[i] > res) res = dp[i];
}
}
}
return res;
}
}
下面我们来看一种优化时间复杂度到O(nlgn)的解法,这里用到了二分查找法,所以才能加快运行时间哇。思路是,我们先建立一个数组ends,把首元素放进去,然后比较之后的元素,如果遍历到的新元素比ends数组中的首元素小的话,替换首元素为此新元素,如果遍历到的新元素比ends数组中的末尾元素还大的话,将此新元素添加到ends数组末尾(注意不覆盖原末尾元素)。如果遍历到的新元素比ends数组首元素大,比尾元素小时,此时用二分查找法找到第一个不小于此新元素的位置,覆盖掉位置的原来的数字,以此类推直至遍历完整个nums数组,此时ends数组的长度就是我们要求的LIS的长度,特别注意的是ends数组的值可能不是一个真实的LIS,比如若输入数组nums为{4, 2, 4, 5, 3, 7},那么算完后的ends数组为{2, 3, 5, 7},可以发现它不是一个原数组的LIS,只是长度相等而已,千万要注意这点。
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
int len = 0;
for(int x : nums) {
int i = Arrays.binarySearch(dp, 0, len, x);
if(i < 0) i = -(i + 1);
dp[i] = x;
if(i == len) len++;
}
return len;
}
参数:a - 要搜索的数组fromIndex - 要搜索的第一个元素的索引(包括)toIndex - 要搜索的最后一个元素的索引(不包括)key - 要搜索的值返回:如果它包含在数组的指定范围内,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 插入点 被定义为将键插入数组的那一点:即范围中第一个大于此键的元素索引,如果范围中的所有元素都小于指定的键,则为 toIndex。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
Longest Increasing Subsequence
标签:return code 完整 [] max war 注意 problem strong
原文地址:http://www.cnblogs.com/apanda009/p/7100064.html