一、题目描述
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1: 输入:nums = [10,9,2,5,3,7,101,18] 输入:nums = [0,1,0,3,2,3] 输入:nums = [7,7,7,7,7,7,7] 提示: 1 <= nums.length <= 2500 |
二、题目难度:中等
三、题解
方法一:动态规划
时间复杂度:O(n^2)
空间复杂度:O(n)
class Solution { public int lengthOfLIS(int[] nums) { int n = nums.length; if(n==0) return 0; int[] dp = new int[n]; dp[0] = 1; int res = 1; for(int i=1;i<n;i++){ dp[i] = 1; for(int j=0;j<i;j++){ if(nums[j]<nums[i]){ dp[i] = Math.max(dp[i],dp[j]+1); } } res = Math.max(res,dp[i]); } return res; } }
方法二:贪心 + 二分查找
1 class Solution { 2 public: 3 int lengthOfLIS(vector<int>& nums) { 4 int n = nums.size(); 5 if(n==0) return 0; 6 int len = 1; 7 vector<int> d(n+1); 8 d[len] = nums[0]; 9 for(int i=1;i<n;i++){ 10 if(nums[i]>d[len]){ 11 len++; 12 d[len] = nums[i]; 13 }else{ 14 int left = 1,right = len-1; 15 int pos = 0; 16 while(left<=right){ 17 int mid = left + ((right - left)>>1); 18 if(d[mid]<nums[i]){ 19 pos = mid; 20 left = mid + 1; 21 } 22 else 23 right = mid - 1; 24 } 25 d[pos + 1] = nums[i]; 26 27 } 28 } 29 return len; 30 } 31 };