Problem:
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?
Idea:
Dynamic Programming
Time Complexity:
O(n^2)
Solution 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Author: Huahua // Running time: 29 ms class Solution { public: int lengthOfLIS(vector<int>& nums) { if (nums.empty()) return 0; int n = nums.size(); auto f = vector<int>(n, 1); for (int i = 1; i < n; ++i) for (int j = 0; j < i; ++j) if (nums[i] > nums[j]) f[i] = max(f[i], f[j] + 1); return *max_element(f.begin(), f.end()); } }; |
1 |
Solution 2: DP + Binary Search / Patience Sort
dp[i] := smallest tailing number of a increasing subsequence of length i + 1.
dp is an increasing array, we can use binary search to find the index to insert/update the array.
ans = len(dp)
Time complexity: O(nlogn)
Space complexity: O(n)
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Solution { public: int lengthOfLIS(vector<int>& nums) { const int n = nums.size(); if (n == 0) return 0; vector<int> dp; for (int i = 0; i < n; ++i) { auto it = lower_bound(begin(dp), end(dp), nums[i]); if (it == end(dp)) dp.push_back(nums[i]); else *it = nums[i]; } return dp.size(); } }; |
Python3
1 2 3 4 5 6 7 8 9 10 |
class Solution: def lengthOfLIS(self, nums: List[int]) -> int: d = [] for x in nums: i = bisect_left(d, x) if i == len(d): d.append(x) else: d[i] = x return len(d) |
Related Problems: