2017-01-29 8 views
0

私はCが新しくなったので、私はleetcodeを通して学びたいと思っています。文字列中の最初の一意の文字を見つけるのにこのCプログラムが遅すぎるのはなぜですか?

https://leetcode.com/problems/first-unique-character-in-a-string/

これは質問の文字列が与えられ

、それに最初の非繰り返し文字を見つけて、それがインデックスのリターンです。存在しない場合は-1を返します。

例:

S = "leetcode" リターン0

S = "loveleetcode"、 リターン2.

そして、これは私のコード

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

int firstUniqChar(char* s) { 
    int c = 0; 
    int freq[26] = {0}; 

    while (s[c] != '\0') { 
    if (s[c] >= 'a' && s[c] <= 'z') { 
     freq[s[c] - 'a']++; 
    } 
    c++; 
    } 

    int firstChar = -1; 
    for (int i = 0; i < strlen(s); i++) { 
    if (freq[s[i] - 'a'] == 1) { 
     firstChar = i; 
     break; 
    } 
    } 
    return firstChar; 
} 

Iであります時間制限を超えていると言われているので、自分のコードが正しいことを証明することはできません。だから、私のプログラムは遅すぎると思っています。どこが間違っているのか分かりませんか?

+2

最初に行うことは、 'i melpomene

+0

また、2番目のループで '(s [c]> = 'a' && s [c] <= 'z')'であるかどうかをテストしてください。そうしないと、配列の範囲外メモリアクセスが発生する可能性があります。 – Siguza

+1

あなたの最初のループは "偶然" "s"の長さを決定するので、あなたはそれを無料で得ることができます。しかし、コードの後半で、 's'の長さを無意識に何度も計算します。パフォーマンスを気にする人は、同じことを繰り返し何度も計算しないでください。 –

答えて

3

strlen(s)がO(n)時間を要し、2番目のループの各繰り返しで実行されるため、コードが誤ってO(n^2)になっています。最初のループのように、あなたが\0文字を見つけるまで繰り返すことができます:正確さに

for (int i = 0; s[i] != '\0'; i++) { 

を:彼らは範囲a-zであるが、あなたの第二のループがない場合は、あなたの最初のループは、文字のみをカウントします。これは、最初のループでチェックが冗長であるか、または2番目のループが間違っていることを意味します(範囲a-zの文字がsにない場合は、freqが範囲外にアクセスするため)。

+0

コードは誤ってO(n^3)です:whileループ、forループ、strlen – Gab

+4

@ GabrieleB-Davidいいえ、O(n + n^2)= O(n^2)。 – Siguza

+0

@ GabrieleB-David whileループとforループは別々で、whileはO(n)とforループO(n^2)です。 –

関連する問題