题目描述
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
C++
方法1:
class Solution {
/*
动态规划
dp[i]存放以nums[i]结尾的最长严格上升子序列的长度
时间复杂度:O(n)
*/
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size()==0) return 0;
vector<int> dp(nums.size(),1);
int res=1;
for(int i=1;i<nums.size();i++){
for(int j=0;j<i;j++){
if(nums[j]<nums[i]){
dp[i]=max(dp[i],dp[j]+1);
}
}
res=max(res,dp[i]); //省了一次遍历专门求最大值
}
return res;
}
};
方法2
贪心+二分查找
class Solution {
/*
贪心+二分查找
如果我们要使上升子序列尽可能的长,则我们需要让序列上升得尽可能慢,因此我们希望每次在上升子序列最后加上的那个数尽可能的小。
维护子序列d[],遍历数组,对于每次的num[i],利用二分查找在d[]中找第一个小于nums[i]的位置K,然后将nums[i]跟新到d[k+1]
*/
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size()==0) return 0;
vector<int> d(nums.size());
int len=1;
d[len]=nums[0];
for(int i=1; i<nums.size();i++){
if(d[len]<nums[i]){
d[++len]=nums[i];
continue;
}
int left=1;
int right=len;
int pos=0;
while(left<=right){
int mid=left+(right-left)/2;
if(nums[i]>d[mid]){
left=mid+1;
pos=mid; //最小值的最右边界,找d中从后向前第一个大于它的元素
}
else{
right=mid-1;
}
d[pos+1]=nums[i];
}
}
return len;
}
};
该博客介绍了如何解决LeetCode上的第300题,即寻找给定整数数组中的最长严格递增子序列。通过提供C++代码,博主分别展示了动态规划和贪心+二分查找两种方法来求解问题,帮助读者理解并实现最长递增子序列的查找算法。
1901

被折叠的 条评论
为什么被折叠?



