• 300. Longest Increasing Subsequence


    class Solution {
        public int lengthOfLIS(int[] nums) {
            int []tails=new int[nums.length];
            int size=0;
            for(int x:nums)
            {
                int i=0,j=size;
                while(i!=j)
                {
                    int m=i+(j-i)/2;
                    if(tails[m]<x)
                        i=m+1;
                    else
                        j=m;
                }
                tails[i]=x;
                if(i==size)++size;
            }
            return size;
        }
    }

    这题是典型的考察dp并且是非常直白的..不像有些题目很绕,想半天才知道是dp

    dp的做法就是分配一个数组,  dp[i] 代表 第i 个位置的最长递增数组长度

    递推公式   if (num[i]>num[k]) dp[i]=max(dp[k]+1,dp[i])    0<=k<i     时间复杂度 O(n2)   n是数组长度;      其实精确计算复杂度应该是O(1+2+3+...+n)  = O(n*(n-1)/2) = O( (n2-n)/2)

    好了, 上面给出的更加高效的办法, 用二分查找做到了 O(nlogn);

    原理如下

    1 数组长度为n,  所以我们可以找出 长度 为  1,2,3,4, ....  k  的递增数组

    2  设定 数组=   1,2,3,0

    长度=1  递增数组   [1], [2] , [3] , [0]

    长度=2 递增数组   [1,2]  [2,3] [1,3] 

    长度=3                   [1,2,3]

    取每个数组的末尾值, 并且值最小    分别是  0 , 2, 3  ;   这几个数的长度是3, 所以答案就是3

    3 实现过程

    分配一个数组来存放不同长度的递增数组的末尾值的最小取值.. 非常绕

    int  tail = new  int[]

    遍历数组;如果 num[i] 比 tail 末尾值还大, 插入末尾

    如果nums[i] 值在tail 的之内;  找到一个位置替换,   具体是   tail[i] < num[j] <= tail[i+1]

    因为用到了二分查找, 所以复杂度变成了logn

  • 相关阅读:
    toj 2819 Travel
    toj 2807 Number Sort
    zoj 2818 Prairie dogs IV
    zoj 1276 Optimal Array Multiplication Sequence
    toj 2802 Tom's Game
    toj 2798 Farey Sequence
    toj 2815 Searching Problem
    toj 2806 Replace Words
    toj 2794 Bus
    css截取字符
  • 原文地址:https://www.cnblogs.com/lychnis/p/9309758.html
Copyright © 2020-2023  润新知