【问题标题】:Determine running time of the code确定代码的运行时间
【发布时间】:2015-09-30 07:51:18
【问题描述】:

我今天编写了以下 dp 代码,它运行良好,因为它获得了一些提交点 (here is the problem)。但是我无法确定我的代码的运行时间。我觉得它是O(n^2 * log D),但我无法证明这一点。

class Solution {
public:
    unordered_map<string, bool> m;
    bool wordBreak(string s, unordered_set<string>& wordDict) {
        int n = s.length();
        string t = "";
        for(int i=0;i<n;i++){
            t += s.at(i);
            //cout << t << endl;
            if(wordDict.find(t) != wordDict.end()){
                m[t] = true;
                string x = "";
                for(int j=i+1;j<n;j++){
                    x += s.at(j);
                }
                if(x == ""){
                    return true;
                }
                if(m.find(x) != m.end()){
                    if(m[x] == true){
                        return true;
                    }else{
                        continue;
                    }
                }else{
                    if(wordBreak(x, wordDict)){
                        m[x] = true;
                        return true;
                    }else{
                        //cout << x << endl;
                        m[x] = false;
                        continue;
                    }
                }
            }else{
                //m[t] = false;
            }
        }
        return false;
    }
};

【问题讨论】:

  • 通常测量这涉及到检测代码将计数器以查看您在代码中使用不同值 ND 等执行某件事的次数(迭代、比较等) , 并将结果绘制在结果图中,或者执行相同的操作,但使用 ND 的不同值测量执行所需的时间。同样O(x) 给出“占主导地位的x”,所以除非log D 很大,而N 很小,否则N^2 将占主导地位,所以值为O(N^2),即使存在,技术上也是@987654333 @参与)。

标签: c++ dynamic-programming asymptotic-complexity


【解决方案1】:

它似乎具有O(n*n) 的复杂性。您使用记忆,算法的每一步都会在m 中产生至少 1 个新值。任何字符串中都有 n*n/2 子字符串,因此在最坏的情况下,您将找到具有 n*n/2 段落的整个字符串的解决方案。

PS:考虑 unordered_map 与 O(1) 一起使用。

编辑:

在您的情况下,考虑 unordered_map 与 O(n) 一起使用可能更合适。 m.find 需要为其参数计算哈希,即字符串。如果您存储索引而不是字符串本身,可能会更快。

【讨论】:

    【解决方案2】:

    首先我会重写如下(未经测试):

    class Solution {
    public:
        unordered_map<string, bool> m;
        bool wordBreak(string s, unordered_set<string>& wordDict) 
        {
            while (!s.empty())
            {
            int n = s.size() ;
            for(int i=0;i<n;i++){
                //cout << t << endl;
                if(wordDict.find(s.substr(0, i)) != wordDict.end()){
                    m[t] = true;
                    s = s.substr(i) ;
                    break ;
            }
            return !m.empty();
        }
    };
    

    基本思想是,一旦找到匹配项,就可以从字符串中删除匹配的部分。然后我会说它是 n * logD。毕竟,你只在 for 循环上做了一次。假设您在 m

    【讨论】:

    • s.substr(0, i) - 这个操作是O(i),你为所有0 &lt;= i &lt; N做这件事。所以总共是O(n^2)
    【解决方案3】:

    我是这样解决的。

    bool wordBreak(string s, unordered_set<string>& wordDict) {
        if (s.empty()) return true;
    
        vector<bool> dp(s.size(), false);
        for (int i = 0; i < dp.size(); ++i)
        {
            for (int j = i; j >= 0; --j)
            {
                if (wordDict.find(s.substr(j, i - j + 1)) != wordDict.end() &&
                    (j == 0 || dp[j - 1]))
                {
                    dp[i] = true;
                    break;
                }
            }
        }
    
        return dp.back();
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-16
      相关资源
      最近更新 更多