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();
        }
    };
    
    每一篇博客,不为别的,证明我的成长。每一次发文,不为别的,证明我严阵以待。蜗牛爬得很慢,却终有一日登上参天大树。因为它热爱。
  • 相关阅读:
    149. Max Points on a Line(js)
    148. Sort List(js)
    147. Insertion Sort List(js)
    146. LRU Cache(js)
    145. Binary Tree Postorder Traversal(js)
    144. Binary Tree Preorder Traversal(js)
    143. Reorder List(js)
    142. Linked List Cycle II(js)
    141. Linked List Cycle(js)
    140. Word Break II(js)
  • 原文地址:https://www.cnblogs.com/agui521/p/12493605.html
Copyright © 2011-2022 走看看