下面是我的代码:
/**
* @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)次吗?请提供见识
答案 0 :(得分:1)
让 n 为strs
中的字符串数,并让平均(或最长)字符串长度为 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行)的执行次数。如您所述,因为 n = strs.length
,所以for循环执行了 n 次。但是,在while循环中确实有return语句,因此执行可能永远不会到达第10行。
现在,对于while循环。如前所述,此循环执行的是前缀( m )的大小,并且在每次迭代中,indexOf操作在最坏的情况下都使用 O(m ^ 2)(请参见下一个)段)。因此,算法的时间复杂度与字符串数( n )的关系为 O(nm ^ 2)。
我们还可以将时间复杂度视为 m 的函数,即每个字符串中的字符数。比较两个字符串需要多长时间?在这种情况下,Java的实现将采用 O(mk),其中 m 和 k 分别是两个字符串的长度(请参见this question)和String class code了解详情。