Longest Increasing Subsequence
题目链接:https://leetcode.com/problems...
主要两种方法:dp和greedy
dp:用dp table,就是每次找出nums[i]为结尾的最长的increasing串的长度就好了。所以分解成subproblem就是: dp[i] = max(dp[j]) + 1,这个复杂度是O(N^2)。
然后就是greedy + binary search的方法,改进NlogN。用一个数组min[i],i表示increasing sequence的长度为i,min[i]表示长度为i的increasing sequence,最右边的num可能的最小值。整个是patient sort的思路。
http://www.cs.princeton.edu/c...
stack的top元素按从小到大的顺序所以可以binary search。如果允许重复且重复的算在increasing sequence里面,那么重复的element就加到比它大的那个top下面就好了。如果重复的不算的话,就每次找>=的地方,查一下是否是重复,是就不加,不是就往里面加。
如果求路径就加个parent point的辅助数组。这里只要求长度即可,那就直接用top(min)就可以了,整个用个数组就行了。
public class Solution {
public int lengthOfLIS(int[] nums) {
if(nums == null || nums.length == 0) return 0;
/* greedy + binary search
* min[i]: minimum rightmost element in increasing sequence with length = i + 1
*/
int[] min = new int[nums.length+1];
min[0] = nums[0];
int index = 0;
for(int i = 1; i < nums.length; i++) {
// new one >= rightmost one, increase the length of sequence
if(nums[i] > min[index]) {
min[++index] = nums[i];
}
// new one < leftmost, update the leftmost
else if(nums[i] <= min[0]) {
min[0] = nums[i];
}
// new one between [0, index + 1], find the place k that
// min[k-1] < nums[i] <= min[k], update min[k]
else {
int k = binarySearch(min, nums[i], 0, index);
min[k] = nums[i];
}
}
return index + 1;
}
private int binarySearch(int[] min, int x, int l, int r) {
while(l + 1 < r) {
int mid = l + (r - l) / 2;
if(min[mid] >= x) r = mid;
else l = mid;
}
if(min[l] >= x) return l;
return r;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。