300. Longest Increasing Subsequence(DP)
1 //Old 2 class Solution { 3 public int lengthOfLIS(int[] nums) { 4 int max = 0; 5 int n = nums.length; 6 if(n == 0) return 0; 7 int[] res = new int[n]; 8 for(int i = 0; i < n; i++) { 9 res[i] = 1; 10 for(int j = 0; j < i; j++) { 11 if(nums[j] < nums[i]) { 12 res[i] = Math.max(res[i], res[j] + 1); 13 } 14 } 15 max = res[i] > max ? res[i] : max; //放到外面的循环 方便点 16 } 17 return max; 18 } 19 }
O(nlogn):
Arrays.binarySearch()的返回值找到关键字从0开始,没找到关键字从1开始
dp数组记录的是从长度1开始,每个长度(1,2,3...)末端的最小值,因为往后遍历的时候,能大于之前值的数肯定能大于这个最小值。判断一个数的时候,找出比这个数大的最小的那个,把那个更新为这个数,代表这个长度下末端的最小值可以是在判断的这个数。要是在判断的这个数是最大的,则在下一个空的地方放置这个数。最后dp数组的有意义长度就是最长递增子序列的长度。
用len记录dp数组的有意义长度。
1 //New 2 3 class Solution { 4 public int lengthOfLIS(int[] nums) { 5 int n = nums.length; 6 int[] dp = new int[n]; 7 int len = 0; 8 for(int num : nums) { 9 int i = Arrays.binarySearch(dp, 0, len, num); 10 if(i < 0) { 11 i = -(i + 1); 12 } 13 dp[i] = num; 14 if(i == len) len++; 15 } 16 return len; 17 } 18 19 }