查阅更多的题解,请点击
Problem
300. Longest Increasing Subsequence(Medium)
Given an unsorted array of integers, find the length of longest increasing subsequence.
Example:
Input: [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
Note:
- There may be more than one LIS combination, it is only necessary for you to return the length.
- Your algorithm should run in O(n2) complexity.
Follow up:
Could you improve it to O(n log n) time complexity?
Solution
设输入数组大小为n
DP O(n^2) time, O(n) space
观察原问题,可以被reduce成较小的问题:求以第i个元素作为结尾的子序列长度,记作DP[i],则可以得到以下的递归表达式:
D P [ i + 1 ] = m a x { { D P [ i ] + 1 if nums[i]>nums[j] 1 if nums[i] <= nums[j] , j < i } DP[i+1]=max\{ \begin{cases} DP[i]+1& \text{if nums[i]>nums[j]}\\ 1& \text{if nums[i] <= nums[j]} \end{cases}, j<i\} DP[i+1]=max{{DP[i]+11if nums[i]>nums[j]if nums[i] <= nums[j],j<i}
class Solution
{
public:
int lengthOfLIS(vector<int> &nums)
{
if (nums.size() < 2)
return nums.size();
int n = nums.size();
int res = 1;
vector<int> dp(n, 1);
for (int i = 1; i < n; ++i)
{
for (int j = 0; j < i; ++j)
{
if (nums[i] > nums[j])
dp[i] = max(dp[i], dp[j] + 1);
}
res = max(res, dp[i]);
}
return res;
}
};
O(nlogn) time, O(n) space
class Solution
{
public:
int lengthOfLIS(vector<int> &nums)
{
if (nums.size() < 2)
return nums.size();
int n = nums.size();
int length = 1;
vector<int> tails(n, 0);
tails[0] = nums[0];
for (int i = 0; i < n; ++i)
{
if (tails[0] > nums[i])
tails[0] = nums[i];
else if (nums[i] > tails[length - 1])
tails[length++] = nums[i];
else
{
auto it = std::lower_bound(tails.begin(), tails.begin() + length, nums[i]);
*it = nums[i];
}
}
return length;
}
};