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?
这道题目是经典的最长递增子串问题,虽然LeetCode标记为中等难度,我觉得应该是hard难度。
最传统的动态规划的做法是O(N^2)的时间复杂度,我就不提供解法了,着重讲一下O(n log n)的解法。
详细讲解可以看这个网站:最长的子序列大小(N log N) - GeeksforGeeks
Java解法如下:
class Solution {
public int CeilIndex(int A[], int l, int r, int key)
{
while (r - l > 1) {
int m = l + (r - l) / 2;
if (A[m] >= key)
r = m;
else
l = m;
}
return r;
}
public int lengthOfLIS(int A[])
{
int size=A.length;
if (size==0) return 0;
// Add boundary case, when array size is one
int[] tailTable = new int[size];
int len; // always points empty slot
tailTable[0] = A[0];
len = 1;
for (int i = 1; i < size; i++) {
if (A[i] < tailTable[0])
// new smallest value
tailTable[0] = A[i];
else if (A[i] > tailTable[len - 1])
// A[i] wants to extend largest subsequence
tailTable[len++] = A[i];
else
// A[i] wants to be current end candidate of an existing
// subsequence. It will replace ceil value in tailTable
tailTable[CeilIndex(tailTable, -1, len - 1, A[i])] = A[i];
}
return len;
}
}
C++解法如下:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> res;
for(int i=0; i<nums.size(); i++) {
auto it = std::lower_bound(res.begin(), res.end(), nums[i]);
if(it==res.end()) res.push_back(nums[i]);
else *it = nums[i];
}
return res.size();
}
};
python解法如下:
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
n = len(nums)
def lower_bound(arr, l, r, value):
while l < r:
mid = (l + r) // 2
if arr[mid] < value:
l = mid + 1
else:
r = mid
return l
dp = []
for n in nums:
i = lower_bound(dp, 0, len(dp), n)
if i == len(dp):
dp.append(n)
else:
dp[i] = n
return len(dp)
最长递增子序列O(nlogn)算法解析

388

被折叠的 条评论
为什么被折叠?



