文章目录
Leetode300(子序列不连续)
1.问题描述
2.解决方案
代码sxl上有详细解答,这只做强调
1.犯了一个不过脑子错误,最后要求的值不一定处在那个序列范围中,所以其实是dp[0]…dp[len-1]中的最大值,而不是dp[len-1]
2.初始化都是1
3.递推也不错多看一看
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
//1.
int len=nums.size();
//2.
vector<int> dp(len,1);
//3.
int ans=-1;
for(int i=0;i<len;i++){
for(int j=0;j<i;j++){
if(nums[j]<nums[i]){
dp[i]=max(dp[i],dp[j]+1);
}
}
ans=max(ans,dp[i]);
}
//4.
//return dp[len-1]; 没过脑子错误
return ans;
}
};
class Solution {
public int lengthOfLIS(int[] nums) {
//1.
int len = nums.length;
int[] dp = new int[len];
Arrays.fill(dp, 1);
//2.
for(int i=0;i<len;i++){
int max = -1;
boolean isMax = false;
for(int j=0;j<i;j++){
if(nums[j]<nums[i]){
isMax = true;
max = Math.max(max, dp[j]);
}
}
if (isMax){
dp[i]=max+1;
}
}
//3.
int res = -1;
for(int i=0;i<len;i++){
res = Math.max(res, dp[i]);
}
return res;
}
}
NC91(子序列不连续)
1.问题描述
2.解决方案
解法一:动态规划(超时)
和上一题300,解法一模一样,这个向前查询的思路也很巧妙,需要关注一下,因为最小的数往往在后面
import java.util.*;
public class Solution {
public int[] LIS (int[] arr) {
//1.
int len = arr.length;
int[] dp = new int[len];
Arrays.fill(dp, 1);
int max = -1;
for(int i=0;i<len;i++){
for(int j=0;j<i;j++){
if(arr[j]<arr[i]){
dp[i] = Math.max(dp[i], dp[j]+1);
max = Math.max(max, dp[i]);
}
}
}
//2.
int[] ans = new int[max];
for(int i=len-1, j=max-1;j>=0;i--){
if(dp[i]==max){
ans[j] = arr[i];
j--;
max--;
}
}
return ans;
}
}
解法二:动态规划+二分
class Solution {
public:
vector<int> LIS(vector<int>& arr) {
int n = arr.size();
vector<int> d(n + 1, -1), p(n);
int len = 1;//初始化长度为1,元素为序列第一个数字
d[len] = arr[0];
p[0] = 1;
for(int i = 1; i < n; ++i) {
if(arr[i] > d[len]) {
//此时将该数字添加到末尾
d[++len] = arr[i];
p[i] = len;
} else {
//二分查找恰好合适的位置
int left = 1, right = len, pos = 0;
while(left <= right) {
int mid = (left + right) / 2;
if(d[mid] < arr[i]) {
pos = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
//对该位置数字进行更新
d[pos + 1] = arr[i];
p[i] = pos + 1;
}
}
vector<int> ans(len);
//逆向查找对应序列值
for(int i = n - 1; i >= 0; --i) {
if(p[i] == len) {
ans[--len] = arr[i];
}
}
return ans;
}
};
Leetode674(子序列连续)
1.问题描述
2.解决方案
代码sxl上有详细过程,这只做强调
1.dp[i]含义应该是以i结尾的最长长度
2.初始化都是1
3.递推就按照题意想出
4.一个没考虑周全的错误,初始化了ans=-1,这是如果len==1的数组for循环会直接被跳过,拿结果就变成了-1,既然我们把过程分析的很清楚了,那就大胆一点就是1,因为最小值就是1
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
//1.
int len=nums.size();
//2.
vector<int> dp(len,1);
//3.
int ans=1;
for(int i=1;i<len;i++){
if(nums[i-1]<nums[i])
dp[i]=max(dp[i],dp[i-1]+1);
ans=max(ans,dp[i]);
}
//4.
return ans;
}
};