zoukankan      html  css  js  c++  java
  • 300. 最长递增子序列

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

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

    示例 1:

    输入:nums = [10,9,2,5,3,7,101,18]
    输出:4
    解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
    

    示例 2:

    输入:nums = [0,1,0,3,2,3]
    输出:4
    

    示例 3:

    输入:nums = [7,7,7,7,7,7,7]
    输出:1
    

    提示:

    • 1 <= nums.length <= 2500
    • -104 <= nums[i] <= 104

    进阶:

    • 你可以设计时间复杂度为 O(n2) 的解决方案吗?
    • 你能将算法的时间复杂度降低到 O(n log(n)) 吗?

     O(NlogN)

    class Solution {
        public int lengthOfLIS(int[] nums) {
            int maxL=0;
            int[] dp=new int[nums.length];//所有长度为i+1的递增子序列中, 最小的那个序列尾数.
            //由定义知dp数组必然是一个递增数组, 可以用 maxL 来表示最长递增子序列的长度. 
            for(int num:nums){
                int index=Arrays.binarySearch(dp,0,maxL,num);
                if(index<0)index=-(index+1);
                dp[index]=num;//将num添加入dp数组尾部
                if(index==maxL)maxL++;//表示num比所有已知递增序列的尾数都大,将最长递增序列长度maxL加1
            }
            return maxL;
        }
    }

     O(N^2)

    class Solution:
        def lengthOfLIS(self, nums: List[int]) -> int:
            n=len(nums)
            if n==0:
                return 0
            dp=[1]*n#dp[i] 表示以 nums[i] 结尾的最长上升子序列的长度
            ans=1
            for i in range(n):
                for j in range(i):
                    #遍历到 nums[i] 的时候,我们应该把下标区间 [0, ... ,i - 1] 的 dp 值都看一遍
                    #如果当前的数 nums[i] 大于之前的某个数,那么 nums[i] 就可以接在这个数后面形成一个更长的上升子序列
                    if nums[i]>nums[j]:
                        dp[i]=max(dp[i],dp[j]+1)#把前面的数都看了, dp[i] 就是它们的最大值加 1。即比当前数要小的那些里头,找最大的,然后加 1 。
                        ans=max(ans,dp[i])
            return ans
  • 相关阅读:
    Accoridion折叠面板
    mui列表系列
    按照中文首字母排序查询表数据
    五分位算法
    springmvc添加拦截器
    springmvc添加定时任务
    通过后台解决跨域调用接口问题
    eclipse搭建ssm框架
    Java 将图片转成base64,传到前台展示
    用mysql存储过程代替递归查询
  • 原文地址:https://www.cnblogs.com/xxxsans/p/14483777.html
Copyright © 2011-2022 走看看