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

    LeetCode_300 最长上升子序列

    description:

    给定一个无序的整数数组nums,找到其中最长上升子序列的长度。

    示例:

    输入: [10,9,2,5,3,7,101,18]
    输出: 4
    解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
    说明:

    可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
    你算法的时间复杂度应该为 O(n2) 。
    进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

    思路:

    思路一:直接粗暴,O(n^2)动态规划

    这个思路比较简单粗暴,定义dp[i]为以[0,i]为区间的,且以nums[i]为尾的最长上升子序列的值。循环遍历数组nums,当遍历到nums[i]时,dp[0]~dp[i-1]都已经算出来了。
    那么状态转移方程为:

        dp[i] = max(dp[j])+1;其中  0<=j<=i-1;
    

    代码:

    class Solution {
    public:
        int lengthOfLIS(vector<int>& nums) {
            int n = nums.size();
            if(!n)
                return 0;
            int dp[n];
            int ans = 1;
            for(int i=0;i<nums.size();i++){
                dp[i] = 1;
                for(int j=0;j<i;j++){
                    if(nums[i]>nums[j]){
                        dp[i] = max(dp[i],dp[j]+1);
                        ans = max(ans,dp[i]);
                    }
                }
                ans = max(ans,dp[i]);
            }
            return ans;
    
        }
    };
    

    复杂度分析:

    时间复杂度:O(n^2),双层遍历

    空间复杂度:O(n),需要一个dp数组

    思路二:二分+贪心

    这个思路比较tricky,不容易想到。
    维护一个数组dp,dp[i]表示以i+1为最长上升子序列的最后一个元素,可以证明dp数组是严格递增的。
    遍历nums,然后去dp中寻找第一个比nums大的数(这里用到二分查找,查找floor),然后替换它;如果nums>dp.back(),直接将nums添加到dp的末尾;

    class Solution {
    public:
        int lengthOfLIS(vector<int>& nums) {
            int n = nums.size();
            if(!n)
                return 0;
            vector<int> dp;
            dp.push_back(nums[0]);
            for(int i=1;i<n;i++){
                if(nums[i]>dp.back()){
                    dp.push_back(nums[i]);
                }else{
                    int l = 0;
                    int r = dp.size()-1;
                    while(l<r){
                        int mid = l + (r-l)/2;
                        if(dp[mid]<nums[i]){
                            l = mid+1;
                        }else{
                            r = mid;
                        }
                    }
                    dp[l] = nums[i];
                }
            }
            return dp.size();
        }
    };
    
    每一篇博客,不为别的,证明我的成长。每一次发文,不为别的,证明我严阵以待。蜗牛爬得很慢,却终有一日登上参天大树。因为它热爱。
  • 相关阅读:
    程序员眼中的 SQL Server-执行计划教会我如何创建索引?
    SQL Server死锁排查
    详解Java中的clone方法 -- 原型模式
    sql-索引的作用(超详细)
    java.util.ConcurrentModificationException 解决办法
    SqlServer索引的原理与应用
    数据库性能优化三:程序操作优化
    数据库性能优化二:数据库表优化
    数据库性能优化一:数据库自身优化(大数据量)
    SQL索引一步到位
  • 原文地址:https://www.cnblogs.com/agui521/p/12493605.html
Copyright © 2011-2022 走看看