【问题标题】:How do I calculate the runtime complexity of this implementation of longest common prefix algorithm?如何计算最长公共前缀算法的这种实现的运行时复杂度?
【发布时间】:2018-11-15 16:07:50
【问题描述】:

下面是我的代码:

/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function(strs) {
    if(strs.length ===0) return '';
    let prefix = strs[0];
    for(let i=0; i< strs.length; i++) {
        while(strs[i].indexOf(prefix) !=0) {
            prefix = prefix.substring(0, prefix.length -1);
            if(!prefix) return '';
        } 
    }

    return prefix;
};

这里 for 循环运行 O(n) 次,while 循环检查前缀是否与 for 循环迭代中的元素匹配 - while 循环也是 O(n) 次吗?请提供见解

【问题讨论】:

    标签: algorithm runtime time-complexity


    【解决方案1】:

    nstrs 中的字符串数,并让平均(或最长)字符串长度为 m。您的行号算法如下。

    1. var longestCommonPrefix = function(strs) {
    2.    if(strs.length ===0) return '';
    3.    let prefix = strs[0];
    4.    for(let i=0; i< strs.length; i++) {
    5.        while(strs[i].indexOf(prefix) !=0) {
    6.            prefix = prefix.substring(0, prefix.length - 1);
    7.            if(!prefix) return '';
    8.        } 
    9.     }
    10.    return prefix;
    11. };
    

    我们只需要估计for循环(第4行)和while循环(第5行)的执行次数。正如您所指出的,for 循环执行了 n 次,因为 n = strs.length。但是,您在 while 循环中确实有一个 return 语句,因此执行可能永远不会到达第 10 行。

    现在,对于 while 循环。如前所述,此循环以前缀 (m) 的大小执行,并且在每次迭代中,indexOf 操作在最坏情况下采用 O(m^2)(请参阅下一个段落)。因此,作为字符串数 (n) 的函数的算法的时间复杂度为 O(nm^2)

    我们还可以将时间复杂度视为 m 的函数,即每个字符串中的字符数。比较两个字符串需要多长时间?在这种情况下,Java 的实现将采用 O(mk),其中 mk 分别是两个字符串的长度(参见这个答案this question) 和String class code 了解详情。

    【讨论】:

    • 非常感谢@rrufai,但在阅读了上面分享的链接中的一个 cmets 后,我又有了疑问。根据 Andreas,O(m^2) 是最坏的情况,也是最不可能的,cos 模式匹配将在第一次不匹配发生并摊销后立即停止,它是 O(1.1 * n),即 O(n)。那么我们是计算平均情况还是最坏情况?
    • @novembersky:通常,对于大 O 分析,我们采用最坏的情况。事实上,它有时被称为最坏情况分析。我希望这会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多