• 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

  • 相关阅读:
    vc++操作mysql数据库的技巧
    [翻译]用表单字段加亮的方式为用户提供友好的界面
    设计方法开篇
    周末之个人杂想(五)
    ComponentArt对Atlas的集成
    [翻译]使用ASP.NET2.0的ReportViewer查看RDLC报表
    [视频讲解]GridView里做链接实现新闻列表到详细内容页的跳转
    关于正则表达式
    周末之个人杂想(七)

  • 原文地址:https://www.cnblogs.com/lychnis/p/9309758.html
Copyright © 2020-2023  润新知