300 最长递增子序列
动态规划
class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
Arrays.fill(dp,1);
dp[0] = 1;
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[i]>nums[j]){
dp[i]=Math.max(dp[i],dp[j]+1);
}
}
}
int res=dp[0];
for (int i=1;i<n;i++){
res=Math.max(res,dp[i]);
}
return res;
}
}
时间复杂度
O
(
n
2
)
O(n^2)
O(n2)。
空间复杂度
O
(
n
)
O(n)
O(n)。
贪心+二分查找
class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] d = new int[n + 1];
int len = 1;
//数组 d[i] ,表示长度为 i 的最长上升子序列的末尾元素的最小值
d[1] = nums[0];
for (int i = 1; i < n; i++) {
if (nums[i] > d[len]) {
len++;
d[len] = nums[i];
} else {
//否则在d[1...len]中找到d[j-1]<nums[i]<d[j],更新d[j]=nums[i]
//下面是找j-1
int l=1;
int r=len;
int mid=(l+r)/2;
int tmp=0;
while(r>=l){
if (nums[i]>d[mid]){
tmp=mid;
l=mid+1;
}else{
r=mid-1;
}
mid=(l+r)/2;
}
//如果tmp还是等于0,说明所有都比num[i]大
//这时更新d[0]
d[tmp+1]=nums[i];
}
}
return len;
}
}
时间复杂度
O
(
n
log
n
)
O(n\log n)
O(nlogn)。
空间复杂度
O
(
n
)
O(n)
O(n)。