目标:函数,它接受指向字符串和两个长度的指针,并在内部字符串之间交换,长度为而不是,使用额外的内存,这取决于输入的大小。 例如,给定字符串" abcdef123"和长度6,3结果应该是" 123abcdef"。
一种可能的递归实现(我的)是:
void invertStrings(char* str, int len1, int len2){
if(len1==0 || len2==0)
return;
if(len1>len2){
for(int i=0;i<len2;++i)
swapChars(str, len1+i, len1-len2+i);
invertStrings(str,len1-len2,len2);
}
else{
for(int i=0;i<len1;++i)
swapChars(str, len1+i, i);
invertStrings(str+len1,len1,len2-len1);
}
}
我认为时间复杂度是O(len1 + len2),甚至可能是O(max {len1,len2})。
问题:时间复杂度是多少?如何证明? 感谢。
答案 0 :(得分:3)
所写的算法似乎是O(len1+len2)
。让我们将函数调用的“总工作量”定义为len1 + len2
。每次调用该函数时,它都会进行min(len1,len2)
交换,并以total_work[n+1] = total_work[n] - min(len1,len2)
递归调用自身。因此,在所有递归调用中完成工作的上限仅为len1+len2
。
此处的附加扭曲是终止条件取决于gcd(len1,len2)
。当len1,len2中的一个为0时,循环终止,因此我们保证交换的数量严格小于len1+len2
。最后“遗留”多少取决于两个长度的gcd。例如,如果我们以(6,3)
为起点,那么我们将获得(6,3)->(3,3)->(0,3)
,总共6次掉期(小于预期的8次)。但如果我们从(7,3)->(4,3)->(1,3)->(1,2)->(1,1)->(1,0)
开始,我们最终会进行9次互换。互换的数量通常是len1 + len2 - gcd(len1,len2)
。
答案 1 :(得分:0)
O(n),因为每次交换操作都会将至少一个字符置于正确的最终位置。
算法复杂度是输入大小的函数,这里操作的成本随着输入的大小线性增长。
通常,由于复杂性,您只关心它所展示的增长类型。如果它是线性的,你不关心系数是什么(例如,你不关心它是输入数据量的两倍还是7)。