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。。。。。