leetcode300,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?
Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.
Subscribe to see which companies asked this question
言归正传,这个题目使用动态规划来解,从第一个数开始,算出在每个下标上的最长递增长度,然后取其中最大的一个即可。此时需要一个数组保存每个下标位置上的结果,假设这个数组为len,长度与目标数组相同,并设其第一个元素为1。接着开始从目标数组的第二个下标开始遍历,嵌套的第二个循环从数组头开始,直到当前的下标,获得当前下标为终点的序列的最大递增长度,存放在len数组中,一直遍历完为止,将最大值返回。可能说起来比较抽象,看下代码,用实际数字试一下会更好理解。
这只是一种方法,嵌套循环,耗时比较多,还有一种二分法,先上第一种的代码。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if (nums.size() == 0)
{
return 0;
}
vector<int> len(nums.size());
len[0] = 1;
int maxlen = 1;
for (int i = 1; i < nums.size(); ++i)
{
int max = 0;
for (int j = 0; j < i; ++j)
{
if (nums[i] > nums[j] && len[j] > max)
{
max = len[j];
}
}
len[i] = max + 1;
if (len[i] > maxlen)
{
maxlen = len[i];
}
}
return maxlen;
}
};
class Solution {
public:
int Bsearch(vector<int> len, int start, int end, int key)
{
if (start == end)
{
return key > len[start] ? start : start - 1;
}
while (start <= end)
{
int mid = (start + end) / 2;
if (key > len[mid] && key < len[mid + 1])
{
return mid;
}
else if (key < len[mid])
{
end = mid - 1;
}
else if (key > len[mid])
{
start = mid + 1;
}
else if (key == len[mid])
{
return mid - 1;
}
}
return 0;
}
int lengthOfLIS(vector<int>& nums) {
if (nums.size() == 0)
{
return 0;
}
vector<int> len(nums.size() + 1);
int maxlen = 1;
int n;
len[1] = nums[0];
for (int i = 1; i < nums.size(); ++i)
{
if (nums[i] > len[maxlen])
{
n = ++maxlen;
}
else
{
n = Bsearch(len, 1, maxlen, nums[i]) + 1;
}
len[n] = nums[i];
}
return maxlen;
}
};
两种算法时长相差了90ms。。。。。