2016-10-07 10 views
0

私はHackerrankの問題を今解決していますが、私の論理は多かれ少なかれ正しいと信じていますが、大規模なデータセットはパフォーマンスを落として「間違った」答えを与えています。あなたはそれをチェックアウトすることができますので、ここでの問題へのリンクは次のとおりです。大きな配列を操作する際のパフォーマンスを向上させる方法は?

https://www.hackerrank.com/challenges/qheap1

私は大きなデータセットを可能にするように、このスクリプトのパフォーマンスを向上する方法を疑問に思って。私はスキャナと関係がありますが、それはなぜか分かりません。

public class Solution { 
    private static final int ADD = 1; 
    private static final int DELETE = 2; 
    private static final int GET = 3; 
    private static final int TICK = 1; 
    public static void main(String[] args) { 
     /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */ 
     Scanner in = new Scanner(System.in); 
     PrintStream out = System.out; 
     int n = in.nextInt(); 
     int[] heap = new int[n]; 

     int a = 0; 
     while (a < n) { 
      a = 0; 
      int q = in.nextInt(); 

      switch(q) { 
       case(ADD): 
        int nextAdd = in.nextInt(); 
        /*out.println("ADD " + next);*/ 
        int b = 0; 
        while (b < n) { 
         /*out.println(heap[b]);*/ 
         if (heap[b] == 0) { 
          heap[b] = nextAdd+TICK; 
          /*printArray(heap);*/ 
          b = n-1; 
         } 
         b++; 
        } 
        /*printArray(heap);*/ 
        break; 
       case(DELETE): 
        int c = 0; 
        int nextDelete = in.nextInt(); 
        while (c < n) { 
         if (heap[c]-TICK == nextDelete) { 
          heap[c] = 0; 
          c = n-1; 
         } 
         c++; 
        } 
        /*printArray(heap);*/ 
        break; 
       case(GET): 
        Arrays.sort(heap); 
        int d = 0; 
        while (d < n) { 
         if (heap[d] != 0) { 
          out.println(heap[d]-TICK); 
          d = n-1; 
         } 
         d++; 
        } 
        /*printArray(heap);*/ 
        break; 
      } 
      a++; 
      /*printArray(heap);*/ 
     } 
    } 

    public static void printArray(int[] ar) { 
     String str = ""; 
     for (int i : ar) { 
      str += i + " "; 
     } 
     System.out.println(str); 
    } 
} 
+1

ヒント:一般的にcodereview.stackexchange.com – GhostCat

+0

になるかもしれない「作業」のコードのため:あなたは**可読性を上で動作する場合があります**最初。あなたのコードが何をしているのかを考えるのは本当に苦労します。たとえば、スイッチのケースを個々のメソッド(メソッドや変数に適した名前)にプッシュすると便利です。コードを見るだけでそのようなパフォーマンスの問題を解決するのは難しい**ですが、そのコードが読みにくい方法で書かれていれば、簡単にはなりません。 – GhostCat

+0

あなたのalghoritmはちょうど二次的な複雑さを持っています。つまり、各反復で 'a'を実行すると、すべてのヒープをトラバースします。あなたは 'a'で' n'繰り返しを行い、それらのそれぞれは別の 'n'回繰り返すでしょう(' b'、 'c''または' d'を使って ' 'n * logn')。 @Lashaneによって提案された目的に合った正しいデータ構造を実装することで改善することができます。 'PriorityQueue'のソースコードを見てみましょう。配列の上に構築されていますが、要素の特別な順序付けを適用するので、要素の大部分をスキップして速度を上げることができます。 – bashnesnos

答えて

1

あなたのコードを見て、私は見つけることができる唯一の当面問題は、このライン

out.println(heap[d]-TICK); 

がコメントアウトされていないという事実です。これは、あなたのJavaプログラム(いいえ、スクリプトではありません)がIO操作をたくさんしていることを意味する可能性があります。そして、それらは非常にあなたのプログラムで起こっていると比較して高価です。

だから、コメントして何が起こるかを見てください。

+0

私は、はい、それは理にかなっています。 'out.println(heap [d] -TICK)'を実行する代わりに、静的で空の文字列 'HEAP'を初期化し、' HEAP + = Integer.valueOf(ヒープ[d] - TICK).toString()+ "
";そのようにして、入力の大部分が終了した後、私は単にそのStringを分割して各番号を出力するだけでした。しかし、私は以前と同じ性能の問題に遭遇しました。理論的には、それはまともなプロセスかもしれないと思う。 –

1

ヒープを使用しない(チャレンジで必要な)主な問題は、配列の操作に時間を費やしていることです。ここで

は、すべてのテストに合格実装です:

public static void main(String[] args) { 
    final Scanner in = new Scanner(System.in); 

    final int n = in.nextInt(); 
    final PriorityQueue<Integer> q = new PriorityQueue<>(n); 
    for (int i = 0; i < n; i++) { 
     final int command = in.nextInt(); 
     switch (command) { 
     case 1: 
      q.add(in.nextInt()); 
      break; 
     case 2: 
      q.remove(in.nextInt()); 
      break; 
     case 3: 
      System.out.println(q.peek()); 
      break; 
     } 
    } 
} 
+0

おそらく正解です。私はまだこのような "ハッキング"の問題を解決しようとする人が本当に "完全な"答えを得ることに本当に興味があるかどうか疑問に思っています。あなたが知っているのは、他の人が完全な解決策を受けてパズルを "解決"する点は何ですか... "解決するための助け"を求めるとき... – GhostCat

+0

@GhostCat私はそれがハッキングまたはパズルあなたが適切なデータ構造を使用していない限り、簡単なアルゴリズム演習を行うことができます。すべてのテストに合格することはできません。 –

+0

@Lashane、理由はわかりませんが、Hackerrankのすべてのパズルを配列で解決しようとしています。私はコレクションフレームワーク(あなたが提供したエレガントなソリューション)から何かを使用することの魅力を確かに見ることができます。専門家としてはそうするのが賢明だと思いますが、この場合のパフォーマンスについてはまだ興味があります。 –