Skip to content

Commit 103403d

Browse files
committed
lengh of lis
1 parent cc45eae commit 103403d

File tree

1 file changed

+52
-25
lines changed

1 file changed

+52
-25
lines changed

basic_algorithm/dp.md

+52-25
Original file line numberDiff line numberDiff line change
@@ -348,38 +348,65 @@ int minCut(string s) {
348348

349349
> 给定一个无序的整数数组,找到其中最长上升子序列的长度。
350350
351-
```go
352-
func lengthOfLIS(nums []int) int {
353-
// f[i] 表示从0开始到i结尾的最长序列长度
354-
// f[i] = max(f[j])+1 ,a[j]<a[i]
355-
// f[0...n-1] = 1
356-
// max(f[0]...f[n-1])
357-
if len(nums) == 0 || len(nums) == 1 {
358-
return len(nums)
359-
}
360-
f := make([]int, len(nums))
361-
f[0] = 1
362-
for i := 1; i < len(nums); i++ {
363-
f[i] = 1
364-
for j := 0; j < i; j++ {
365-
if nums[j] < nums[i] {
366-
f[i] = max(f[i], f[j]+1)
351+
```c++
352+
#pragma region 复杂度O(n^2)
353+
int lengthOfLIS1(vector<int>& nums) {
354+
if (nums.size() < 2) {
355+
return nums.size();
356+
}
357+
358+
vector<int> cache(nums.size());
359+
cache[0] = 1;
360+
for (int i = 1; i < nums.size(); ++i) {
361+
cache[i] = 1;
362+
for (int j = 0; j < i; ++j) {
363+
if (nums[j] < nums[i]) {
364+
cache[i] = max(cache[i], cache[j] + 1);
367365
}
368366
}
369367
}
370-
result := f[0]
371-
for i := 1; i < len(nums); i++ {
372-
result = max(result, f[i])
368+
auto maxLen = cache[0];
369+
for (const auto &item : cache) {
370+
maxLen = max(maxLen, item);
373371
}
374-
return result
375-
372+
return maxLen;
376373
}
377-
func max(a, b int) int {
378-
if a > b {
379-
return a
374+
#pragma endregion
375+
376+
#pragma region 复杂度O(n log n)
377+
// 题目给了提示,看到log n可以考虑往二分查找之类的上凑
378+
int lengthOfLIS(vector<int> &nums) {
379+
int size = nums.size();
380+
if (size < 2) {
381+
return size;
380382
}
381-
return b
383+
384+
// tail[i]表示长度为i + 1的子序列的最小末尾值
385+
// tail必定单调递增,单调栈
386+
// 如果当前节点大于栈顶,即,比最长子序列的末尾还大,入栈(长度+1
387+
// 否则通过二分查找找到第一个比当前节点大的值,进行更新。子序列长度相同,末尾节点变小
388+
vector<int> tail;
389+
tail.push_back(nums.front());
390+
for (int i = 1; i < size; ++i) {
391+
if (nums[i] > tail.back()) {
392+
tail.push_back(nums[i]);
393+
continue;
394+
}
395+
auto left = 0;
396+
auto right = tail.size() - 1;
397+
while (left < right) {
398+
int mid = left + (right - left) / 2;
399+
if (tail[mid] < nums[i]) {
400+
left = mid + 1;
401+
} else {
402+
right = mid;
403+
}
404+
}
405+
tail[left] = nums[i];
406+
}
407+
return tail.size();
382408
}
409+
#pragma endregion
383410
```
384411
385412
### [word-break](https://leetcode-cn.com/problems/word-break/)

0 commit comments

Comments
 (0)