运行时间比较 - 类似的代码运行速度慢 4 倍

Comparison of running times - similar code runs 4 times slower

本文关键字:运行 速度慢 代码 比较 运行时间      更新时间:2023-10-16

我正在解决回文分区问题,该问题需要返回给定字符串(http://oj.leetcode.com/problems/palindrome-partitioning/)的所有回文分区。我找到了这个问题的两个解决方案。我很难理解为什么这两种方法的运行时间存在巨大差异:

(假设bool isPal()是一个给定的函数,它告诉给定的字符串是否在O(长度)时间内是回文)

第一个解决方案:(使用回溯):

void find(string s, int start, vector<string> &r, vector<vector<string> > &res){
    if (start >= s.size()){
        res.push_back(r);
    }else{
    for (int i=start;i<s.size();i++){            
        if (isPal(s.substr(start, i-start+1))){
            r.push_back(s.substr(start,i-start+1));
            find(s,i+1,r,res);        
            r.pop_back();
        }  
    }
    }  
}
vector<vector<string>> partition(string s) {
    vector<vector<string> > res;
    vector<string> r;
    find(s,0,r,res);
    return res;    
}

第二个解决方案:

vector<vector<string> > partition(string s) {
    vector<vector<string> > answer;
    if(s.size() == 0)
        return answer;
    // if s is Palindrome, push to answer
    if(isPal(s))
        answer.push_back(vector<string>(1,s));
    if(s.size() == 1)
        return answer;
    for(int i=1; i<s.size(); ++i) {
        string s1 = s.substr(0, i);
        string s2 = s.substr(i, s.size()-i);
        if(isPal(s1)) {
            // get sub_answers of partition(s[i:])
            vector<vector<string> > sub_answer = partition(s2);
            // add s1 to the begin of sub_answers
            for(int j=0; j<sub_answer.size(); ++j) {
                sub_answer[j].insert(sub_answer[j].begin(), s1);
                answer.push_back(sub_answer[j]);
            }
        }
    }
    return answer;
}

尽管两种解决方案具有相同的基本思想,但第一个解决方案的运行时间为 108 毫秒,而第二个解决方案需要 472 毫秒的时间。这是因为理论上效率低下(也许第二个解决方案多次解决单个问题)还是因为实施效率低下(一些C++概念)?请指出第二个解决方案效率低下的原因。

注意:两种解决方案都是正确的,并给出相同的结果。

我假设两个实现返回相同的结果?除此之外,还有几行值得评论:

sub_answer[j].insert(sub_answer[j].begin(), s1);

这迫使sub_answer[j]的所有内容向后移动,以便为s1留出空间。最好在添加其余部分之前将s1添加到载体中。

answer.push_back(sub_answer[j]);

现在再次复制sub_answer[j]。由于您不再需要sub_answer[j],因此您可以使用std::move来交换所有权而不是复制:

answer.push_back(std::move(sub_answer[j]));