n^2做法
import java.util.Arrays;
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
for (int i = 0; i < len; i++) {
for (int j = 0; j < i; j++) {
if(nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
return Arrays.stream(dp).max().getAsInt() + 1;
}
}
nlogn做法
class Solution {
public int lengthOfLIS(int[] nums) {
ArrayList<Integer> dp = new ArrayList<>();
for (int num : nums) {
int len = dp.size();
if (len == 0 || num > dp.get(len - 1)) {
dp.add(num);
} else {
int l = 0;
int r = len - 1;
while (l < r) {
int mid = (l + r) >> 1;
if (num > dp.get(mid)) {
l = mid + 1;
} else {
r = mid;
}
}
dp.set(r, num);
}
}
return dp.size();
}
}
这题比较特别的是dp[i]指的是长度为i的末尾最小值
擅用api~
处理过的index是这个数在dp数组里应该插入的位置
class Solution {
public int lengthOfLIS(int[] nums) {
List<Integer> dp = new ArrayList<>();
dp.add(nums[0]);
int len = nums.length;
for (int i = 1; i < len; i++) {
int size = dp.size();
int index = Collections.binarySearch(dp, nums[i]);
if (index < 0) {
index = -index-1;
} else {
continue;
}
if (index == size) {
dp.add(nums[i]);
} else {
dp.set(index, Math.min(dp.get(index), nums[i]));
}
}
return dp.size();
}
}
如果题目要求最长不递减子序列,我们将else里的内容修改一下,
如果找到了,我们应该向后检索到第一个不相等的位置,这才是它该插进去的地方
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
int size = 0;
for (int i = 0; i < len; i++) {
int index = Arrays.binarySearch(dp, 0, size, nums[i]);
if (index < 0) {
index = -index - 1;
} else {
continue;
}
if (index == size) {
dp[size++] = nums[i];
} else {
dp[index] = Math.min(dp[index], nums[i]);
}
}
return size;
}
}