300. 最长递增子序列
给你一个整数数组 nums
,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]
是数组 [0,3,1,6,2,2,7]
的
子序列
。
示例 1:
1 2 3
| 输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
|
示例 2:
1 2
| 输入:nums = [0,1,0,3,2,3] 输出:4
|
示例 3:
1 2
| 输入:nums = [7,7,7,7,7,7,7] 输出:1
|
提示:
1 <= nums.length <= 2500
-10^4 <= nums[i] <= 10^4
进阶:
- 你能将算法的时间复杂度降低到
O(n log(n))
吗?
动态规划,线性dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution { public int lengthOfLIS(int[] nums) { int n = nums.length, f[] = new int[n+1], res = 0; Arrays.fill(f, 1); for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { if (nums[i] > nums[j]) f[i+1] = Math.max(f[i+1], f[j+1]+1); } res = Math.max(res, f[i+1]); } return res; } }
|
也可以用贪心思想,维护一个自增序列
a数组:
- 10
- 9
- 2
- 2 5
- 2 3
- 2 3 7
- 2 3 7 101
- 2 3 7 18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public int lengthOfLIS(int[] nums) { int n = nums.length; int a[] = new int[n]; int cnt = 0; for (int i = 0; i < n; i++) { int l = 0, r = cnt; while (l < r) { int m = (l + r)/2; if (a[m] < nums[i]) l = m + 1; else r = m; } a[l] = nums[i]; if (l == cnt) cnt++; } return cnt; } }
|