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

Lines changed: 52 additions & 25 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy