300. Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence.
For example,
Given [10, 9, 2, 5, 3, 7, 101, 18]
,
The longest increasing subsequence is [2, 3, 7, 101]
, therefore the length is 4
. Note that 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?
方法一、动态规划的方法,时间复杂度O(N*N)
思路:采用dp数组来保存,到达dp[i]的最大长度,其中dp[i]=max(dp[i],dp[i-1]+1)。求数组的最长递增子序列。经典dp问题,在很多大学讲DP的教程里,
都会出现这道题以及Longest Common Subsequence。 这里其实也有O(nlogn)的方法,比如Patience Sorting一类的,二刷再研究。下面我们来看DP。
这个问题一开始可以被分解为recursive的子问题,一步一步优化就可以得到带有memorization的iterative解法。初始化dp[i] = 1,即一个元素的递增序列。
假设以i - 1结尾的subarray里的LIS为dp[i - 1],那么我们要求以i结尾的subarray里的LIS,dp[i]的时候,要把这个新的元素和之前所有的元素进行比较,
同时逐步比较dp[j] + 1与dp[i],假如发现更长的序列,我们则更新dp[i] = dp[j] + 1,继续增加j进行比较。当i之前的元素全部便利完毕以后,我们得到了
当前以i结尾的subarray里的LIS,就是dp[i]
int lengthOfLIS(vector<int>& nums) {
int len = nums.size();
vector<int> dp(len,1);
int maxLen = 0;
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);
}
maxLen = max(maxLen,dp[i]);
}
return maxLen;
}
方法二、 排序+LCS算法