// dp 无后序性
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
Arrays.fill(dp, 1);
int res = 0;
for(int i=0;i<len;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[j]) dp[i] = Math.max(dp[j] + 1, dp[i]);
}
res = Math.max(res, dp[i]);
}
return res;
}
}
// 二分法
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
int[] tail = new int[len];
int res = 0;
for(int num: nums){
int l = 0, r = res;
while(l < r){
int m = (l + r) >>> 1;
if(tail[m] < num) l = m + 1;
else r = m;
}
tail[l] = num;
if(res == l) res++;
}
return res;
}
}
进阶:输出对应序列
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
int[] tail = new int[len];
int[] maxLen = new int[len];
int res = 0;
for(int i = 0; i < len; i++){
int num = nums[i];
int l = 0, r = res;
while(l < r){
int mid = (l + r) >>> 1;
if(tail[mid] < num) l = mid + 1;
else r = mid;
}
tail[l] = num;
maxLen[i] = l;
if(res == r) res++;
}
int[] ans = new int[res];
for(int i = len - 1, j = res - 1; j >= 0;--i){
if(maxLen[i] == j){
System.out.println(i);
ans[j--] = nums[i];
}
}
for(int i=0;i<res;i++){
System.out.println(ans[i]);
}
return res;
}
}
class Solution {
public int findNumberOfLIS(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
int[] g = new int[len];
Arrays.fill(dp, 1);
Arrays.fill(g, 1);
int res = 0;
for(int i=0;i<len;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[j]) {
if(dp[i] == dp[j]+1){
g[i] += g[j];
}else if(dp[i] < dp[j]+1){
dp[i] = dp[j] + 1;
g[i] = g[j];
}
}
}
res = Math.max(res, dp[i]);
}
int ans = 0;
for(int i=0;i<len;i++){
if(dp[i] == res) ans+=g[i];
}
return ans;
}
}