HashSetとTreeSetの検索速度比較
-
HashSet
HashSetは内部でハッシュ化によってデータを保存します。各要素の位置はハッシュ関数で計算され、データの順序は保証されませんが、平均**O(1)**の時間で素早く検索できるため、特定の要素が存在するかどうかを確認する場合に非常に効率的です。 -
TreeSet
TreeSetは二分木構造(実際には赤黒木構造)でデータを整列された状態で保存します。このため、要素を追加または削除する際には**O(log n)の時間がかかり、検索も同様にO(log n)**の時間が必要です。このような特性から、整列が必要な場合や範囲検索をする場合には適していますが、単純な存在確認ではHashSetよりも遅くなります。
HashSet vs TreeSetの選択理由
- このアルゴリズムでは整列は必要なく、特定の数が存在するかだけを確認すればよいため、
HashSetが最も適しています。 - 要素を自動的に整列させる必要があったり、範囲検索が必要な場合には
TreeSetが有効ですが、連続数列の始点を素早く見つけるためにはHashSetの方が効率的です。
アルゴリズムの説明
HashSetを利用した連続数列の値を求めるアルゴリズム (TreeSetとの検索速度比較)
public int solution(int[] nums){
int answer = 0;
HashSet<Integer> set = new HashSet<>();
for(int a : nums){
set.add(a);
}
int max = 0;
for (int num : nums) {
if (set.contains(num - 1)) {
int curVal = num;
int count = 1;
while (set.contains(curVal)) {
curVal += 1;
count++;
}
max = Math.max(max, count);
}
}
answer = max;
return answer;
}
このコードは、与えられた配列 numsの中で最も長い連続した数列を見つけ出すアルゴリズムです。配列内の連続する数値が最も長く続く場合の長さを求めることが目標です。このアルゴリズムでは、HashSetを使用して重複を除去し、効率的な検索によって最大の連続数列の長さを計算します。ここでは、TreeSetを使用した場合との検索速度も比較して説明します。
-
重複を除去し検索準備を行う
HashSetを利用してnums配列の重複要素を取り除き、効率的に検索できるようにします。HashSet<Integer> set = new HashSet<>(); for(int a : nums){ set.add(a); } -
最大の長さを保存する変数を初期化
連続した数列の最大の長さを追跡するためにmax変数を初期化します。int max = 0; -
連続した数列を見つける
各数字numに対して以下の処理を行います:-
数列の始点を確認する
num - 1がsetに存在するかを確認します。num - 1が存在する場合、numは連続数列の始点ではないためスキップし、num - 1が存在しない場合のみ始点とみなします。 -
数列の探索と長さの計算
始点numから始まり、1ずつ増加するcurValを追いかけながら、setにその値が存在する限りcountを増やして連続する数列の長さを求めます。 -
最大長さの更新
得られた数列の長さcountがmaxよりも大きい場合、maxを更新して現在の最大連続数列の長さを記録します。
for (int num : nums) { if (!set.contains(num - 1)) { int curVal = num; int count = 1; while (set.contains(curVal + 1)) { curVal += 1; count++; } max = Math.max(max, count); } } -
-
結果を返す
最も長い連続数列の長さをanswerに保存し、返します。answer = max; return answer;
例
配列numsが[100, 4, 200, 1, 3, 2]の場合、1, 2, 3, 4が最長の連続数列であり、countは4となり、返り値も4となります。
まとめ
このアルゴリズムはHashSetを用いて重複を除去し、**O(1)の検索速度で効率的に探索し、最も長い連続数列の長さを求める方法です。TreeSetを使用しても同様の機能は実現できますが、検索にO(log n)**の時間がかかるため、HashSetほど効率的ではありません。