1,问题描述
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
-104 <= nums[i] <= 104
进阶:
- 你能将算法的时间复杂度降低到
O(n log(n))
吗?
2,初步思考
最开始以为使用单调栈来求解,但是我的想法有误
看完题解发现是动态规划和贪心
3,代码处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| import java.util.*;
public class _300最长递增子序列 {
public int lengthOfLIS_dp(int[] nums) { int len = nums.length; int[] dp = new int[len]; dp[0] = 1; for (int i = 1; i < len; i++) { for (int j = 0; j < i; j++) { if (nums[j] < nums[i]) { dp[i] = Math.max(dp[i], dp[j]); } } dp[i] += 1; } return Arrays.stream(dp).max().getAsInt(); }
public int lengthOfLIS_binary_search(int[] nums) { List<Integer> list = new ArrayList<>(); list.add(nums[0]); for (int i = 1; i < nums.length; i++) { if (list.getLast() < nums[i]) { list.add(nums[i]); } else { int idx = Collections.binarySearch(list, nums[i]); if (idx < 0) { idx = -idx - 1; } list.set(idx, nums[i]); } } return list.size(); }
public int lengthOfLIS(int[] nums) { int max = 0; Deque<Integer> stack = new ArrayDeque<>(); for (int num : nums) { if (stack.isEmpty()) { stack.addLast(num); } else { while (!stack.isEmpty() && stack.peekLast() >= num) { stack.pollLast(); } stack.add(num); } max = Math.max(max, stack.size()); } return max; }
public static void main(String[] args) { _300最长递增子序列 longestIncreasingSubsequence = new _300最长递增子序列();
System.out.println(longestIncreasingSubsequence.lengthOfLIS_dp(new int[]{1, 3, 6, 7, 9, 4, 10, 5, 6})); } }
|