web-dev-qa-db-ja.com

JavaでのHashMap.containsValue()の時間の複雑さは何ですか?

O(n)時間の複雑さで解決する問題が与えられました:

「数値と数値xのリストを与えられます。リストに2つの数値が合計してxになるかどうかを調べますか?」

そしてこれが私の解決策です:

_public class SumMatchResult {

  public static void main(String[] args){
    int[] numberList = {6,1,8,7,4,6};
    int requiredSum = 8;
    boolean isSumPresent = checkSumPresentHash(numberList,requiredSum);
    if(isSumPresent) {
      System.out.println("Numbers exist");
    }else {
      System.out.println("Numbers donot exist");
    }
  }

  private static boolean checkSumPresentHash(int[] numberList, int requiredSum) {
    Map<Integer, Integer> m = new HashMap<Integer,Integer>();
    int count = 0;
    for(int i=0;i<numberList.length;i++){
      m.put(i, numberList[i]);
    }
    for(int i=0;i<numberList.length;i++){
      if(m.containsValue(requiredSum - numberList[i])){
        count++;
      }
    }
    if(count>1){
        return true;
    }
    return false;
  }

}
_

私は確かにHashMap.containsValue()の複雑さを持っているHashSet.contains()を使用する代わりにO(1)を使用しています。 。たとえば、上記の場合、_{3,6,4,4,7}_に一致する入力値のセット_sum 8_を設定できます。これにより、trueが返されます。

上記のソリューションの時間の複雑さは、HashMap.containsValue()メソッドの複雑さに依存します。 containsValue()メソッドの時間の複雑さについて少し説明し、時間の複雑さの観点から上記の問題に対するより良い解決策があるかどうかを提案してください。ありがとうございました。

24
Vishnu Vedula

タイトルの質問に答えるために-他の人が述べたように、containsValueはO(n)です。キーがないと、どこにあるのかわからず、アルゴリズムは、地図。

あなたの質問の本文の質問に答えるには-それを解決する方法について-あなたが本当にを見て、各数についてあなたが見たインスタンスの数を数えることができる一般的なマップが必要かどうかを考えてください。つまり、only数値の外観が複数ある場合に気になるのは、x/2のときですよね?それは私には隅っこいにおいがします。そのコーナーケースをチェックするテストを追加するだけです。たとえば、セット構築ループ中にif (numberList[i] == requiredSum/2) half++を埋め込み、その後にif (requiredSum % 2 == 0 && half == 2) return trueを埋め込むようなものです(以下の他のバリエーションを参照)。

次に、セットを反復処理し、各アイテムについてrequiredSum-itemもセットに表示されます。

要約すると(可能な場合は早期終了):

Set<Integer> seen = new HashSet<Integer>();
boolean halfSeen = false;
for (int num : numberList) {
    if (num == requiredSum/2 && requiredSum % 2 == 0) {
        if (halfSeen) return true;
        halfSeen = true;
    } else {
        seen.add(num);
    }
}
for (int num : seen) {
    if (seen.contains(requiredSum - num)) return true;
}
return false;
19
Oak

HashMapは基本的にキー値ストアであり、O(1)の複雑さでキーにアクセスできます。ただし、値を確認する場合、HashMapでできることは何もありません。すべての値を確認して、検索している値と等しいかどうかを確認します。したがって、複雑さはO(n)で、nはHashMapの要素数です。

別のメモ:ボックス型(整数)のコレクションでプリミティブ値(int)を検索しています。つまり、HashMapでメソッドを呼び出すたびに、Javaはプリミティブ値をボックス化する必要があります: http://docs.Oracle.com/javase/1.5.0/ docs/guide/language/autoboxing.html

12
rethab

HashMap.containsValueの複雑度はO(n)です。ただし、nはマップサイズではなく、ハッシュテーブルサイズです。マップサイズ= 0の場合でも、containsValueはすべてのテーブル要素を通過するためです。初期容量= 1024で空のマップを作成したとします。containsValueは、1024要素を通過する必要があります。ハッシュテーブル配列:

public boolean containsValue(Object value) {
    if (value == null)
        return containsNullValue();

    Entry[] tab = table;
    for (int i = 0; i < tab.length ; i++)
        for (Entry e = tab[i] ; e != null ; e = e.next)
            if (value.equals(e.value))
                return true;
    return false;
}
3