@@ -348,38 +348,65 @@ int minCut(string s) {
348
348
349
349
> 给定一个无序的整数数组,找到其中最长上升子序列的长度。
350
350
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);
367
365
}
368
366
}
369
367
}
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);
373
371
}
374
- return result
375
-
372
+ return maxLen;
376
373
}
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;
380
382
}
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();
382
408
}
409
+ #pragma endregion
383
410
```
384
411
385
412
### [word-break](https://leetcode-cn.com/problems/word-break/)
0 commit comments