题目描述

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

示例 2:
输入:nums = [0,1,0,3,2,3]
输出:4

示例 3:
输入:nums = [7,7,7,7,7,7,7]
输出:1

提示:
1 <= nums.length <= 2500
-104 <= nums[i] <= 104

进阶:
你可以设计时间复杂度为 O(n2) 的解决方案吗?
你能将算法的时间复杂度降低到 O(n log(n)) 吗?

题解

动态规划

len[i]表示以nums[i]为尾元素的递增子序列的最大长度。

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[]len=new int[nums.length];

        int max=1;
        for(int i=0;i<nums.length;++i){
            len[i]=1;
            for(int j=0;j<i;++j){
                if(nums[i]>nums[j]&&len[j]+1>len[i]){
                    len[i]=len[j]+1;
                    if(max<len[i]){
                        max=len[i];
                    }
                }
            }
        }
        return max;
    }
}

贪心+动态规划+二分查找(参考官方题解

  • 贪心:对于相同长度的递增子序列而言,尾元素越小,后续元素组成递增子序列的可能性越高。

tail[i]表示长度为i+1的递增子序列尾元素的最小值a。因为长度为i+2的递增子序列的尾元素大于其倒数第二个元素b,且b大于等于a,因此tail[i+1]>tail[i],即tail数组是严格递增的。因此tail数组的更新规则如下:

  • 如果nums[i]>tail数组最后一个元素,则将nums[i]加入tail数组尾部,即递增子序列长度+1。

  • 如果nums[i]<=tail数组最后一个元素,则二分查找tail数组,将大于nums[i]的最小元素替换为nums[i],即对应长度的递增子序列的尾元素变小。

    class Solution {
      public int lengthOfLIS(int[] nums) {
          int[] tail=new int[nums.length];
          int len=0;
    
          // 只有一个元素时,递增子序列长度为1
          tail[len++]=nums[0];
    
          for(int i=1;i<nums.length;++i){
              // 大元素直接加入序列尾部
              if(nums[i]>tail[len-1]){
                  tail[len++]=nums[i];
              }else{
                  int left=0,right=len-1;
                  // 左小右大的元素
                  while(left<right){
                      int mid=(left+right)/2;
                      if(tail[mid]<nums[i]){
                          left=mid+1;
                      }else{
                          right=mid;
                      }
                  }
                  tail[left]=nums[i];
              }
          }
          return len;
      }
    }