给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
递归
int[] f = new int[10000];
int[] p = new int[10000];
public int robot(int idx, int[] nums) {
if (idx < 0) {
return 0;
}
if (f[idx] > 0) {
return f[idx];
}
int ans = 0;
for(int i = 0; i < idx; i++) {
if (nums[idx] > nums[i]) {
ans = Math.max(ans, robot(i, nums));
}
}
f[idx] = ans + 1;
return ans + 1;
}
public int lengthOfLIS(int[] nums) {
for(int i = 0; i < nums.length; i++) {
p[i] = nums[i];
}
int n = nums.length;
p[n] = 1000000;
return robot(n, p) - 1;
}
非递归
非递归
public int lengthOfLIS_1(int[] nums) {
for(int i = 0; i < nums.length; i++) {
p[i] = nums[i];
}
int n = nums.length;
p[n] = 1000000;
n++;
for(int idx = 0; idx < n; idx++) {
int ans = 0;
for(int i = 0; i < idx; i++) {
if (p[idx] > p[i]) {
ans = Math.max(ans, f[i]);
}
}
f[idx] = ans + 1;
}
return f[n - 1] - 1;
}
```
时间复杂度为O(nlogn)
public int lengthOfLIS_2(int[] nums) {
for(int i = 0; i < nums.length; i++) {
p[i] = nums[i];
}
int n = nums.length;
p[n] = 1000000;
n++;
int[] min = new int[10000];
for(int i = 0; i < min.length; i++) {
min[i] = 100000001;
}
int path = 0;
for(int idx = 0; idx < n; idx++) {
int ans = 0;
int L = 0, R = path;
while(L <= R) {
int mid = (L + R) / 2;
if (p[idx] > min[mid]) {
ans = mid;
L = mid + 1;
} else {
R = mid - 1;
}
}
f[idx] = ans + 1;
min[f[idx]] = Math.min(min[f[idx]], p[idx]);
path = Math.max(path, f[idx]);
}
return f[n - 1] - 1;
}
“`