交换2个连续字符串 - 时间复杂度

时间:2012-12-31 15:06:34

标签: c time-complexity c-strings

目标:函数,它接受指向字符串和两个长度的指针,并在内部字符串之间交换,长度为而不是,使用额外的内存,这取决于输入的大小。 例如,给定字符串" 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})。

问题:时间复杂度是多少?如何证明? 感谢。

2 个答案:

答案 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)。