zoukankan      html  css  js  c++  java
  • 300. 最长上升子序列

    题目

    给定一个无序的整数数组,找到其中最长上升子序列的长度。
    
    示例:
    
    输入: [10,9,2,5,3,7,101,18]
    输出: 4 
    解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
    
    说明:
    
        可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
        你算法的时间复杂度应该为 O(n2) 。
    
    进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
    
    

    解析

    • 方法一:方法1:排序+LCS:一个简单的思路是将给定的序列先进行有序化( O(nlog(n))),然后使用LCS算法来查找给定的序列及有序化后的序列之间的最长公共子串(O(n2)),这个方法显然不够好。

    • 方法二:典型的动态规划题目: 时间复杂度为 O(n^2),定义一个数组dp,其中dp[i]代表以第num[i]为结尾取得的最长长度,最后返回最大的那个dp[i]就行了;

    • 方法三: 复杂度O(n*log(n))

    class Solution {
    public:
        int lengthOfLIS(vector<int>& nums) {
            if(nums.empty())
                return 0;
            int n=nums.size();
            vector<int> dp(n); //dp[i]表示0-i的最长递增子序列
            int ret=1;
            for(int i=0;i<n;i++)
            {
                dp[i]=1;
                for(int j=i-1;j>=0;j--)
                {
                    if(nums[i]>nums[j]&&dp[i]<dp[j]+1)
                    {
                        dp[i]=dp[j]+1;
                        if(dp[i]>ret)
                            ret=dp[i];
                    }
                }
            }
            return ret;
        }
    };
    
    
    • 以为是O(n^2)复杂度,结果更新有bug
    int lengthOfLIS(vector<int>& nums) {
    	if (nums.empty())
    		return 0;
    	int n = nums.size();
    	int maxlen = 1;
    	for (int i = 0; i < n - 1; i++)
    	{
    		int ret = 1;
    		int maxValue = nums[i];
    		for (int j = i + 1; j<n; j++)  //bug: [10,9,2,5,3,4] ;输出:2 ; 预期:3
    		{
    			if (nums[j]>maxValue)
    			{
    				ret++;
    				maxValue = nums[j];
    			}
    		}
    		if (ret > maxlen)
    			maxlen = ret;
    	}
    	return maxlen;
    }
    
    
  • 相关阅读:
    HTML
    Java 1.8 新特性
    Java 反射
    子网与超网
    Java 网络编程
    Java 单例模式、枚举
    Java 线程生命周期、线程池
    Java 多线程
    Java Properties、流对象关闭格式
    基础练习 十六进制转八进制
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/9627984.html
Copyright © 2011-2022 走看看