最长上升子序列

 

给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4 
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。

说明:

  • 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
  • 你算法的时间复杂度应该为 O(n2) 。

进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

 


 

思考: 要得到的是最长上升子序列的长度。

    dp[ i ]  表示 前 i 个元素中,最长上升子序列的长度,那么 dp[ i+1 ] 的值 就要根据 nums[ i+1 ] 的值  和 子序列的最后一个值来确定。(子序列可能不止一个!!)    ( 分析的不好!!! )

  动态规划,为什么不是返回 dp 数组的最后一个元素呢?  因此这里的 dp[ i ]表示的是以 nums[ i ]作为上升子序列最后一个元素的 序列的长度。

( 用dp数组的时候,一定要明白数组的元素是什么意思,也就是数组的状态表示的是什么??? )

class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums==null||nums.length==0)
            return 0;
        int res=1;
        int[] dp = new int[nums.length];
        for(int i=0;i<nums.length;i++){
            dp[i]=1;
        }
        for(int i=0;i<nums.length;i++){
            for(int j=0;j<i;j++){
                if(nums[j]<nums[i]){
                    dp[i]=Math.max(dp[i],dp[j]+1);
                    if(res<dp[i])
                        res=dp[i];
                }
            }
        }
        return res;
    }
}

怎么优化成  nlogn 呢?  看到 log n 就想到一般是用二分查找了!!!对于nums 数组的循环肯定是没法优化的,那么就是要去优化第二个循环了!

  (可是第二个循环是无序的啊? 怎么用二分呢?  二分的前提是数组中的元素是有序的啊!!)

 dp 远没有想像中的那么简单!!!

  ( 主要就是dp状态的选择和状态转移方程的确立! ) 这里的dp[ i ]表示的就是当前固定长度下的  长度为 i+1的子序列的最后一个元素的最小值。

class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums==null || nums.length==0)
            return 0;
            // dp[i] 表示前 i+1个元素的子序列的最小值
        int[] dp = new int[nums.length];
        dp[0]=nums[0];
        int end = 0;
        for(int i=1;i<nums.length;i++){
            if(nums[i]>dp[end]){
                end++;
                dp[end]=nums[i];
            }else{
                int left=0,right=end;
                while(left<right){
                    int mid=left+((right-left)>>>1);
                    if(dp[mid]<nums[i])
                        left=mid+1;
                    else
                        right=mid;
                }
                dp[left]=nums[i];
            }
        }
        return ++end;
    }
}

 

posted @ 2020-08-10 16:49  你眼里的星辰  阅读(119)  评论(0)    收藏  举报