• nyoj 17


      最初写的代码太丑陋,所以去掉了。

    ------------update 2018-02-05 12:46:22-------------

      题目例子:

    对于字串:abklmncdefg
    正确答案是:7 (abcdefg)
    
    过程是这样的:abklmn 下一个c就中断了,于是再从头开始检查还有没有更长的:
    abk
    abl
    abm
    abn
    abcdefg
    
    通过匹配发现abcdefg是最长的,所以返回。

      几个月之前搜过这个题,了解到这是一个dp经典题,但我当时并没有dp的概念,所以题解也没看懂...现在我再次尝试解决一下:

    class Solution {
    public:
        int LargestLongSubsequence(char str[]) {
            int Length = (int)strlen(str);
    
            if(Length == 0)
                return 0;
    
            char* sub_str = new char;
    
            for(int i = Length - 1; i >= 0; i--) {
                char s[Length];
                int k = 0;
                for(int j = 0; j <= i; j++) {
                    if(str[j] < str[i] && str[j] < str[j + 1])
                        s[k++] = str[j];
                    else
                        continue;
                }
                s[k] = '';
                //std::cout << s << std::endl;
                if((int)strlen(sub_str) <= (int)strlen(s)) {
                   strcpy(sub_str,s);
                }
            }
            //std::cout << sub_str << std::endl;
    
            return (int)strlen(sub_str) + 1;
        }
    }

      思路:最长递增子序列的最后一个字符肯定是更靠近数组的右端一些。那么这样就可以用一个外层循环从最右边开始递减,再用一个内层循环从最左边的开始递增并和外层的字符进行比较,如果满足比当前右边的小且当前的字符比后一个字符小就加入到新的字符数组中。时间复杂度O(n^2),空间复杂度O(n)。

    --------------------update 2018-02-06 19:49:11---------------------

      代码有bug...没考虑到如这样的字符串:abcabc,我的算法返回结果长度是 5,正确的长度为3。

      正确的dp解法:

    class Solution {
    public:
        int LongestIncreasingSubsequence(string str)
        {
            if(str.empty())
                return 0;
    
            vector<int> dp(str.size(), 1);
            int res = 1;
            for (int i = 1; i < str.size(); i++)
            {
                for (int j = 0; j < i; j++)
                    if (str[j] < str[i])
                        dp[i] = max(dp[i],dp[j] + 1);
                res = max(res, dp[i]);
            }
            return res;
        }
    };
    

      时间复杂度O(n^2),空间复杂度为O(n)。

    ----------------update 2018-02-10 19:44:10-------------

      记录一个O(nlgn)复杂度的算法:

    #include <iostream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    class Solution {
    public:
        int LongestIncreasingSubsequence(string str)
        {
            if(str.empty())
                return 0;
    
            vector<char> res{str[0]};
            for(auto s : str)
            {
                int l = 0, r = res.size() - 1;
                if (res.back() < s) res.push_back(s);
                else
                {
                    while(l < r)
                    {
                        int m = l + (r - l) / 2;
                        if (res[m] < s) l = m + 1;
                        else    r = m;
                    }
                    res[r] = s;
                }
            }
            return (int)res.size();
        }
    };
    
    int main()
    {
        Solution solve;
        string str = "abklmncdefg";
    
        cout << solve.LongestIncreasingSubsequence(str) << endl;
        return 0;
    }
    

      算法很好,但得到的子序列并不是原来的LIS序列,长度一样。

  • 相关阅读:
    MySQL架构备份
    MySQL物理备份 xtrabackup
    MySQL物理备份 lvm-snapshot
    MySQL逻辑备份mysqldump
    MySQL逻辑备份into outfile
    MySQ数据备份
    前端基础-- HTML
    奇淫异巧之 PHP 后门
    php中代码执行&&命令执行函数
    windows进程中的内存结构(缓冲溢出原理)
  • 原文地址:https://www.cnblogs.com/darkchii/p/7449476.html
Copyright © 2020-2023  润新知