LeedCode_最长上升子序列
题目说明
给定一个无序的整数数组,找到其中最长上升子序列的长度。
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
方法一:动态规划,时间复杂度O(n2)
辅助状态数组是记录以i结尾的最长上升序列的数量,所以最后需要遍历状态数组找到最大值
int lengthOfLIS1(vector<int>& nums)
{
int n = nums.size();
if (n == 0)
return 0;
int maxsize=0;
vector<int> f(n,1); //状态位置f(i)表示以i结尾的最大上升序列的数量
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (nums[i] > nums[j])
{
f[i] = max(f[j] + 1, f[i]);
}
}
maxsize = max(maxsize, f[i]);
}
return maxsize;
}
方法二:动态规划+二分查找
此方法利用辅助数组记录当前的最长上升序列,注意代码中的注释部分
int lengthOfLIS2(vector<int>& nums)
{
int n = nums.size();
vector<int>dp; //维护当前的最长序列的内容
for (int i = 0; i < n; i++)
{
int left = 0;
int right = dp.size();
while (left < right)
{
int mid = left + (right - left) / 2;
if (dp[mid] < nums[i])
{
left = mid + 1;
}
else
{
right = mid;
}
}
if (right >= dp.size())
{
dp.push_back(nums[i]); //当前的元素比最大值大,便插入
}
else
{
dp[right] = nums[i]; //当前的元素在范围之内,仅是修改内部的元素(在合适的位置替换元素),不改变数量
}
}
return dp.size();
}