zoukankan      html  css  js  c++  java
  • 【LeetCode & 剑指offer刷题】动态规划与贪婪法题10:Longest Increasing Subsequence

    【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

    Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence.
    Example:
    Input: [10,9,2,5,3,7,101,18]
    Output: 4
    Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
    Note:
    • There may be more than one LIS combination, it is only necessary for you to return the length.
    • Your algorithm should run in O(n2) complexity.
    Follow up: Could you improve it to O(n log n) time complexity?

    C++
     
    //问题:找最长递增子序列(可以不要求连续)
    /*
    方法:动态规划
    dp[i]表示以nums[i]为结尾的最长递增子串的长度
    dp[i] = max(dp[i], dp[j] + 1)
     
     
    O(n^2) O(n)
    */
    class Solution
    {
    public:
        int lengthOfLIS(vector<int>& nums)
        {
            vector<int> dp(nums.size(), 1); //dp值初始化为1,dp[0] = 1,一个元素长度为1
           
            int res = 0;
            for (int i = 0; i < nums.size(); i++) //遍历数组,以num[i]结尾
            {
                for (int j = 0; j < i; j++) //遍历num[i]以前的数(i=0~n-1,j=0~i-1)
                {
                    if (nums[j] < nums[i] )//当遇到递增对时,dp[j]+1,更新dp[i]
                        dp[i] = max(dp[i], dp[j] + 1);
                }
                res = max(res, dp[i]); //选择dp[i]中的最大值,因为不确定以哪个num[i]结尾的递增子序列最长
            }
            return res;
        }
    };
     
    /*
    掌握
    * 方法:动态规划+二分查找
    * 具体过程:dp存最长递增子序列
    注意:数组dp不一定是真实的LIS,只是长度一致
    * 例:
        input: [0, 8, 4, 12, 2]
        dp: [0]
        dp: [0, 8]
        dp: [0, 4]
        dp: [0, 4, 12]
        dp: [0 , 2, 12] which is not the longest increasing subsequence, but length of dp array results in length of Longest Increasing Subsequence.
    * O(nlogn) O(n)
     
    */
    #include <algorithm>
    class Solution
    {
    public:
        int lengthOfLIS(vector<int>& a)
        {
            if(a.empty()) return 0;
            
            vector<int> dp;
            for (int ai : a)
            {
                //lower_bound返回第一个大于等于ai的位置,函数参数为(first,last) last指向区间末尾位置
                //在dp[first,last)序列中寻找ai可以满足增序插入的位置,如果找不到,说明ai比区间所有值大,返回last
                //因为dp维护成一个增序数组,故可用二分查找法
                auto it = lower_bound(dp.begin(), dp.end(), ai); //查找第一个大于等于ai的位置(查找ai可以插入的位置)
                if (it == dp.end()) //如果区间中不存在,则push到末尾
                    dp.push_back(ai);
                else                //如果存在,则替换对应位置的元素
                    *it = ai;
            }
            return dp.size();
        }
    };
     
     
     
  • 相关阅读:
    react路由组件&&非路由组件
    react函数式组件(非路由组件)实现路由跳转
    react使用antd组件递归实现左侧菜单导航树
    【LeetCode】65. Valid Number
    【LeetCode】66. Plus One (2 solutions)
    【LeetCode】68. Text Justification
    【LeetCode】69. Sqrt(x) (2 solutions)
    【LeetCode】72. Edit Distance
    【LeetCode】73. Set Matrix Zeroes (2 solutions)
    【LeetCode】76. Minimum Window Substring
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10229365.html
Copyright © 2011-2022 走看看