使用 strlen() 时超出时间限制错误?

Time limit exceeded error when using strlen()?

以下代码按预期工作,此代码打印字符串中出现次数最多的字符:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {

    long int i,a[26]={0},m=0 ,c=0 ;
    char s[1000001] ;
    scanf("%s",s);
    for (i=0;s[i]!='[=10=]';i++){
        a[s[i]-'a']++;
    }
    for ( i=0 ; i<26 ; i++)
        {
            if ( a[i] > m ) {       
            m = a[i] ;
            c = i ;
            }
        }

    printf("%c",'a' + c);
    return 0;
}

但是当我使用strlen()时它会导致时间限制错误:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {

    long int i,a[26]={0},m=0 ,c=0 ;
    char s[1000001] ;
    scanf("%s",s);
    for (i=0;i<strlen(s);i++){
        a[s[i]-'a']++;
    }
    for ( i=0 ; i<26 ; i++)
        {
            if ( a[i] > m ) {       
            m = a[i] ;
            c = i ;
            }
        }

    printf("%c",'a' + c);
    return 0;
}

问题出在哪里?

char s[1000001]

根据 OS,这对于堆栈来说可能太大了。您应该使用 malloc() 或在文件范围内动态分配。即使堆栈足够大,在堆栈上放置这么大的数组也不是好的做法。

除此之外:strlen() 对每个循环迭代进行评估,在字符串中搜索 NUL 终止符。对于最坏的情况(最大长度),strlen 被处理 1000000 次,搜索 s 的所有 1000001 个位置(O(n**2))。

您应该将其分配给循环外的变量并使用它进行比较:

size_t slen = strlen(s);
for ( i = 0 ; i < slen ; i++ ) {

或者坚持第一个版本,也可以。

for (i=0;i<strlen(s);i++)

此代码正在调用 strlen(s) 函数。它需要 O(n) 时间复杂度。

for (i=0;s[i]!='[=11=]';i++)

此代码不调用任何函数,因此会比之前的代码快得多。

首先,在 i 的每次迭代中检查 s 的长度,并且需要 O(n) 才能找到最后一个 0,因此需要 O(n^2),第二种情况是 O(n)

这里O(n^2)计算量很大