これら2つのサンプルコードが異なるの時間複雑さはどのように、いますか?

Rajnishランジャン:

採用プロセスにおけるいくつかの問題を考えると、この問題はJavaで指定した文字列から最初の非反復文字を見つけることでした。以下のうち最初のものは、すべてのテストケースを通過することができたが、第2期限複雑にテストケースの数に失敗しうち2つのサンプルコードがあります。私はこれらの2つのコードが異なるの時間複雑かどうか、およびその方法を理解するために出て、アルゴリズムと複雑さの解析に新たなんだ、缶誰かの助けを借り、私としては?

サンプルコード1:

public static char firstNonRepeatingCharater(String s) {
    for(int i=0;i<s.length(); i++) {
        if(s.indexOf(s.charAt(i)) == s.lastIndexOf(s.charAt(i))) {
            return s.charAt(i);
        }
    }
    return '_';
}

サンプルコード2:

public static char firstNonRepeatingCharater(String s) {
    for(int i=0;i<s.length(); i++) {
        int count = 0;
        for(int j=s.length()-1;j>=0; j--) {
            if(s.charAt(i) == s.charAt(j)) {
                count++;
            }
        }
        if(count == 1) {
            return s.charAt(i);
        }
    }
    return '_';
}
Menios:

計算複雑

まず第一には、あなたの質問から、私はそれがすぐに理解するためには、良いのだろう実現するtime complexitybig oh notation

以下からの引用ウィキペディア

コンピュータサイエンスでは、時間の複雑さは、それがアルゴリズムを実行するのにかかる時間を説明する計算の複雑です。時間の複雑さは、一般的に、各基本動作を実行するための一定の時間を要するとすると、アルゴリズムによって実行される基本操作の数をカウントすることによって推定されます。[...]このアルゴリズムの実行時間は同じ大きさの異なる入力の間で変えることができるので、一つは一般に、所与のサイズの入力に必要な時間の最大量が最悪の場合の時間複雑さを考えます。

ビッグO記法

アルゴリズムの複雑さは、ランダウの記号に現れる関数の種類に応じて分類されます。例えば、時間複雑度はO(n)とアルゴリズム。いくつかの定数アルファためのO(n)の線形時間アルゴリズムと時間複雑度はO(n ^アルファ)とアルゴリズムである>図1は、多項式時間アルゴリズムです。

2つのコード・サンプルに関連して

2つのコードサンプルを見てください。すぐに我々はいくつかのことに気づきます。

  1. コードのサイズは、試料1においてはるかに小さいです。だから、おそらく我々は、より少ない操作であってもよいです。
  2. さらに重要なことしかし、我々は第二の試料中にネストされたforループに気づきます。最初のサンプルは1を持っていません。これは必ずしもメソッド内のコードの割引隠れたコストを行います。

少しの実験を行うことができます。ときレッツは、(最初の非繰り返しcharが真ん中にある)平均的-悪い状況で必要な操作の数を数えますsize of Z is = 1, 10, 100, and 1000

注:この例では/コスト1の操作は、これは総単純化であると私はそれぞれの行を評価します-実験は思いました。 操作の数をカウントして任意の省略を許します。

Algorithm 1: (size of s, lines executed)
-
1, 3
10, (2*5)+1 = 11
100, (2*50)+1 = 101
1000, (2* 500) + 1 = 1001
Total = (2* N/2 ) + 1 

私たちは、死刑執行の結果数が直線的に初期入力の大きさに関係していることがわかります。

Algorithm 2: (N = size of s, lines executed)
-
1, 7
10, 2(5*5) + 2
100, 2(50*50) + 2
1000, 2(500*500) + 2
Total = ((N/2) *2 + 2*(N/2)*(N/2) + 2

alogirthm 1では、私たちは、複雑さが直線的に、特にSの入力サイズに関係していることを確認しますO(n)アルゴリズム2では、我々はそれが具体的には、多項式時間であることを確認しますO(n^2)我々は考慮の本当のコストがかかる一度しかし、これは間違ってなりindexOflastIndexOf

indexOfとのlastIndexOfのコストを追加します

Let n=Size of the String S

アルゴリズム1:(事業の概算#)

 for(int i=0;i<s.length(); i++) // -  N/2
     if(s.indexOf(s.charAt(i)) == s.lastIndexOf(s.charAt(i))) {  // ~ worst case =  (N/2 + N/2) * N/2
     return s.charAt(i); // 1 operation

     Total = N/2 + (N/2 + N/2)*N/2 +1 
    = N^2/2 + N/2  + 1

アルゴリズム2:(事業の概算#)

    for(int i=0;i<s.length(); i++) { // - executed N/2 times
        int count = 0;               // - executed N/2 times
        for(int j=s.length()-1;j>=0; j--) {  // Executed (n/2 * n/2 )
            if(s.charAt(i) == s.charAt(j)) {  // Executed (n/2 * n/2 ) 
                count++;                      // Executed 1 time 
            }
        }
        if(count == 1) {                      //Evaluated N/2 times
            return s.charAt(i);               // Executed 1 time
        }
    }
    return '_';

Total = N/2 + N/2 + 2(N/2*N/2) + 1
= N^2/2 + N + 1

注:私はかなりの数の単純化をしました。私はまた、非反復文字が文字列(文字配列)の中心(N / 2)に配置されると仮定する。取る主なポイントは、サイズが大きくなるにつれて実行操作増加の推定#ことです。上記の例では、ポイントを証明することを目的としています。100%正確ではありません。

私たちはのindexOfおよびlastIndexOfでもを考える方法また、コメントで指摘したように、全体結果/引数は、あります。我々は、単一の操作としてそれらを考えるのですか?それとも我々はN / 2の操作としてそれらを考慮していますか?それはまたのindexOfおよびlastIndexOfでもの実装に依存します。これらの配列を検索している場合、彼らは隠れてfor loops内部を。彼らがした場合(最後の例)では、両方のアルゴリズムのコストがはるかに同様になります。

Algo1: N^2/4 + N/2  + 1
VS
Algo2: N^2/2 + N + 1

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=20235&siteId=1