最长递增子序列

172 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

来源:力扣(LeetCode)

代码

方法1

  • 一维数组dp[i]表示以i作为结尾的递增子序列的值

  • 遍历到dp[i]向前查找出nums[j]<nums[i]且这个dp[j]的值最大

class Solution {
    public int lengthOfLIS(int[] nums) {
        return lengthOfLISPus(nums);
    }
    public int lengthOfLIS1(int[] nums) {
          int[] dp=new int[nums.length]; //dp[i]表示以i作为结尾的递增子序列的值
          int  longest=1;
          dp[0]=1;
          for(int i=1;i<nums.length;i++){
              int  j=i-1;
              int leftMax=0;
             while(j>=0){ //向前找
                if(nums[j]<nums[i]){
                    leftMax=Math.max(leftMax,dp[j]); //更新
                }
                j--; //向前走
             }
             dp[i]=leftMax+1;
             longest=Math.max(longest,dp[i]);
          }
      
      return longest;
    }


方法2

在1的基础上加入一个一位数组ends[i]表示所有长度为i+1的递增子序列的最小

 public int lengthOfLISPus(int[] nums) {
        int[] dp = new int[nums.length]; //子序列必须以nums[i]最长递增子序列长度
        int[] ends=new int[nums.length]; //ends[i]表示所有长度为i+1的递增子序列的最小结尾nums[i]
        dp[0] = 1;
        int index=0;
        ends[index]=nums[0];
        for (int i = 1; i <nums.length ; i++) {
            int j=index;
            while(j>=0){
                //这个时候j指向最长的序列
                if(nums[i]>ends[index]){
                    j++;
                    ends[j]=nums[i]; //更新ends[j+1]位置上的最小结尾
                    break;
                }
                j--; //j向前走
                //找到ends[j]<nums[i],看看要不要更新
                if(j>=0&&ends[j]<nums[i]){
                    //更新j
                    if(nums[i]<ends[j+1]){
                        ends[j+1]=nums[i];
                    }
                    break;
                }
                
            }
            if(j<0&&ends[0]>nums[i]){
                ends[0]=nums[i];
            }
            //更新index值,index指针指向有效区的位置
            index=Math.max(index,j);
        }
    return index+1;
    }
}