2017-10-07 1 views
-2

n個の整数a1、a2、...、anのシーケンスがあります。シーケンス内のすべての要素を最小要素で変更する必要があります。最小要素はその前に配置されます。そのような要素がない場合は、-1に置き換える必要があります。すべての変更は、同時かつ独立しています。リスト操作アルゴリズムが遅すぎる

例:

4 3 1 2 1 - > -1 4 3 3 2

5 4 3 2 1 - > -1 5 4 3 2

マイコードが遅すぎるとシーケンスが大きすぎるとタイムアウトエラーのテストに合格しません。どのように性能を向上させることができますか?

public static void main(String[] args) throws InterruptedException { 
    ArrayList<Integer> list = new ArrayList<>(); 
    Scanner scanner = new Scanner(System.in); 
    int nElements = scanner.nextInt(); 
    for (int i = 0; i < nElements; i++) { 
     list.add(scanner.nextInt()); 
    } 
    ArrayList<Integer> newList = new ArrayList<>(); 
    for (int i = 0; i < list.size(); i++) { 
     int tmp = -1; 
     for (int j = i - 1; j >= 0; j--) { 
      if (list.get(i) < list.get(j)) { 
       if (list.get(j) < tmp || tmp == -1) { 
        tmp = list.get(j); 
       } 
      } 
     } 
     newList.add(tmp); 
    } 
    list = newList; 
} 

UPDATE:

は、ここに私のコードである私は、新しい値は、我々は変更の要素よりも大きくなければならないことを言及するのを忘れてしまいました。

+1

要件は正確には何ですか?私は例を得ていない。最終的なサイズについての良い見積もりを与えることによって 'ArrayList'をスピードアップできることに注意してください。そのコンストラクタで 'initialCapacity'と伝えます。 – Zabuza

+6

'4 3 1 2 1 - > -1 4 3 1 1'ではないでしょうか? – janos

+1

内部ループは必要ありません。要素iの前の最小要素は(要素i-1の前に最小)と(要素i-1)の最小値です。あなたは1回のパスでそれを行うことができます。 –

答えて

0

ありがとう!木のセットと天井の方法はそれを働かせた:

public static void main(String[] args) throws InterruptedException { 
    ArrayList<Integer> list = new ArrayList<>(); 
    Scanner scanner = new Scanner(System.in); 
    int nElements = scanner.nextInt(); 
    for (int i = 0; i < nElements; i++) { 
     list.add(scanner.nextInt()); 
    } 
    ArrayList<Integer> newList = new ArrayList<>(); 
    TreeSet<Integer> set = new TreeSet<>(); 
    for (Integer aList : list) { 
     Integer tmp = set.ceiling(aList + 1); 
     if (tmp == null) { 
      newList.add(-1); 
     } else { 
      newList.add(tmp); 
     } 
     set.add(aList); 
    } 
    list = newList; 
} 

ありがとうございました!

0
public static void main(String[] args) { 
    int[] values = {10,3,5,7,9,2,2,14,-5,7,9,3}; 

    if (values.length == 0) { return; } 

    int minValue = values[0]; 
    int temp; 
    values[0] = -1; 

    for(int i=1; i<values.length; i++) { 
     temp = values[i]; 
     values[i] = minValue; 
     if (temp < minValue) { 
      minValue = temp; 
     } 
    } 

} 

現在のアイテムまでの最小値を覚えておいて、新しいアイテムを見つけたら交換してください。これはO(N)で実行されており、追加のメモリは必要ありません。

+0

私はあなたのコードは、より小さい値が見つかるまで-1を書き続けていると思います(前の条件がfalseの場合、 'int minValue'行は失敗することに注意してください)。 –

+0

ありがとう@AndyTurner、私は数字を印刷し、それをチェックしなかった私の元のバージョンを編集しました、私の悪い、今働く必要があります:) –

1

現在ネストされたループの構築方法のため、あなたのアプローチは時間的にO(n^2)です(nはリストのサイズです)。

内部ループは必要ありません。リストに追加する次の値、つまり新しいリストの前の値にすでに上限があります。次の要素は、入力リスト内の対応する先行要素が小さい場合にのみ小さくなります。だからちょうどそれらの2つの数字の小さい方を取る。 CPPの初心者のアドバイスに

List<Integer> newList = new ArrayList<>(); 
if (list.size() > 0) { newList.add(-1); } 
if (list.size() > 1) { newList.add(list.get(0)); } 
for (int i = 2; i < list.size(); i++) { 
    newList.add(Math.min(list.get(i-1), newList.get(i-1))); 
} 
+0

私は変更する要素より大きい必要があります新しい値を言及することを忘れていた。したがって、2は1に、3は3に変更することはできません。 – bengan