方法一: 动态规划 (O(n))
class Solution { public int lengthOfLIS(int[] nums) { int n = nums.length; if(n < 2) return n; int[] dp = new int[n+1]; // dp[i] : 以第i个数字结束的最长子序列长度 int res = 0; for(int i = 1; i <= n; i++) { dp[i] = 1; for(int j = i-2; j >= 0; j--) { if(nums[i-1] > nums[j]) { dp[i] = Math.max(dp[i],dp[j+1]+1); } } res = Math.max(res,dp[i]); } return res; } }
方法二: 二分查找(O(n log n))
class Solution { public int lengthOfLIS(int[] nums) { int n = nums.length; int[] arr = new int[n]; int len = 0, res = 0; // len记录长度 for(int num : nums) { int l = 0, r = len - 1; while(l <= r) { // 每次遍历到一个值,插入arr数组第一个大于它的位置,更新长度 int mid = (l + r) >> 1; if(arr[mid] >= num) { r = mid - 1; } else { l = mid + 1; } } if(l == len) len++; // 表示长度增加 arr[l] = num; res = Math.max(res,len);// 每次记录最大长度 } return res; } }