牛课网--最长递增子序列详解

Posted cyx-garen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛课网--最长递增子序列详解相关的知识,希望对你有一定的参考价值。

最长递增子序列

求给定一个数组中,最长递增子序列的长度

(子序列,可以不连续 子数组,需要连续)

Eg: arr={2,1,6,4,5,2,7,4}          最长递增子序列为 {2,4,5,7} 长度为4

解法一  O(n2)

思路:

  1. 生成辅助数组temp,temp[i]代表以arr[i]结尾的情况下的最大子序列长度
  2. 设置temp[i]时,比较arr[i],遍历前方所有比arr[i]小的数,在其集合的最大temp值上加一

 技术分享图片

 

 

缺点:

         在思路(2)中需要遍历arr数组的前方所有比arr[i]小的数,为O(n),整体为O(n2)

 

代码:

    public int[] maxSize()

    {

       int[] arr={2,1,6,4,5,2,7,4};

       int[] temp=new int[arr.length];

       temp[0]=1;

       int max;

       for(int i=1;i<arr.length;i++){

           max=0;

           for(int j=0;j<i;j++){

              if(arr[j]<arr[i]&&max<=temp[j])

                  max=temp[j];

           }

           temp[i]=max+1;

       }

       return temp;

    }

 

 

解法二 O(nlogn)

是对解法一的思路(2)中的改进,使用二分法将复杂度降低

 

思路:

  1. Temp存在有效区的概念,即只在一定区间内数据可以存放
  2. Temp[i]指的是在有效区中,长为i+1的最长子序列的最小末尾值

 

技术分享图片

 

Temp数组的概念与解法一中有所不同(这里比较难理解)

举个例子: temp[1]=6代表的是长度为1+1=2的最长子序列的最小末尾值为6 ,此时若是继续遍历arr,发现存在子序列长度为2但是末尾值小于6的则会替换(2,1,6,2  1,6->1,2),这样做的意义是在于永远保持temp数组的值的最小,以便后续增加

Arr : 2 1 5 7 3            2->1->1,5->1,5,7->1,3,7

1,5,7->1,3,7      意味着遍历到目前为止,长度为2的子序列可以以5结尾,也可以以3结尾,但是为了统计后续的最大值,替换为3结尾的子序列,在此基础上增加 

注意:此时不会影响到前面已经统计的, 1,5,7->1,3,7,  7结尾的最长子序列长度依然是3(子序列为1,5,7),

后面数字为2         1,3,7->1,2,7  长度为2的子序列最小末尾为2  1,2

后面数字为9           1,2,7->1,2,7,9          长度为4的子序列最小末尾为9          1,5,7,9(这个想清楚就理解了)

 

代码:

    //arr>temp,往后  arr<temp,替换
    public int[] maxSizeTwo()
    {
        int[] arr={2,1,6,4,5,2,7,4};
        int[] temp = new int[arr.length];
        int left=0,right=0,count=0,mid;
        temp[0]=arr[0];
        for(int i=1;i<arr.length;i++){
            right=count;
            while(left<right){
                mid=(right+left)/2;
                if(arr[i]<temp[mid]){
                    right=mid-1;
                }
                else
                    left=mid+1;
            }
            if(temp[left]<arr[i]){
                count++;
                temp[left+1]=arr[i];
            }
            else
                temp[left]=arr[i];
        }
        return temp;
    }

 

以上是关于牛课网--最长递增子序列详解的主要内容,如果未能解决你的问题,请参考以下文章

牛客Top200---最长递增子序列(求子序列+长度 画图详解java)

算法--字符串:最长递增子序列LIS

代码随想录算法训练营第五十二天 | 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

用数学语言说一下动态规划求数列最长递增子序列的解

JAVA动态规划,最长递增子序列的代码太难理解,求大神帮我讲解一下!

最长递增子序列