最長の連続シーケンス
タイトル説明
順序付けられていない整数型の配列が与えられた場合、連続する要素の最長シーケンスの長さを見つけます。
例:
指定された配列は[100、4、200、1、3、2]であり、
最長の連続要素シーケンスは[1、2、3、4]です。このシーケンスの長さを返します:4
を指定する必要がありますO(n)内の複雑さを持つ時間アルゴリズム
ソートされていない整数の配列が与えられた場合、最も長い連続した要素シーケンスの長さを見つけます。
たとえば、
Given [100、4、200、1、3、2]の場合、
連続する最長の要素シーケンスは[1、2、3、4]です。その長さを返します:4。
アルゴリズムはO(n)の複雑さで実行する必要があります。
問題解決のアイデア
時間計算量はO(N)のアイデアです:ハッシュテーブル
-
setおよびunordered_setのfind関数の時間計算量について:
- セットの最下層は赤黒木によって実装されているため、その検索関数の時間計算量:O(logn)
- unordered_setの最下層はハッシュテーブルであるため、その検索関数の時間計算量:O(1)
- アルゴリズムの検索関数は順次検索であり、複雑さはO(n)です。
-
setおよびunordered_setの消去機能について:
- st.erase(it):要素を削除する必要があるイテレータです。時間計算量はO(1)であり、find()関数と組み合わせて使用できます。
といったst.erase(st.find(100));//利用find()函数找到100,然后用erase删除
- st.erase(value):valueは削除する必要のある要素の値であり、時間計算量はO(logN)です。
といったst.erase(100); //删除值为100的元素
- st.erase(it):要素を削除する必要があるイテレータです。時間計算量はO(1)であり、find()関数と組み合わせて使用できます。
-
この質問のアイデア:
ハッシュテーブルを使用して、最初に番号をハッシュテーブルにマップし、次に番号ごとに、それを見つけた後に削除し、次に両側を同時に検索し、それがあれば削除しますそれを見つけ、最後に長さを見つけます。
ハッシュテーブル検索はO(1)です。これは、各番号が1回だけ追加され、1回削除されるため、複雑さはO(n)です。 -
Niuke.comでunordered_setを使用する場合は、ヘッダーファイル#include <unordered_set>を追加する必要があることに注意してください。
-
この質問のハッシュテーブルがunordered_mapではなくunordered_setを使用する理由:
unordered_setは、繰り返される要素を含まないコンテナーであり、この質問では、要素の数を考慮せずに要素自体を保持するだけで済みます。 -
ベクトルnumのすべての要素をunordered_setstに初期化します。
unordered_set<int> st(num.begin(), num.end());
#include <unordered_set>
class Solution {
public:
int longestConsecutive(vector<int>& num) {
int size = num.size();
if(size <= 1) return size;
//初始化hash表
unordered_set<int> st(num.begin(), num.end());
int res(0);
for(auto n : num) {
//如果没找到该元素,则直接跳过
if(st.find(n) == st.end()) continue;
int left(n), right(n);
//向左寻找
while(st.find(left - 1) != st.end()) {
st.erase(st.find(-- left));
}
//向右寻找
while(st.find(right + 1) != st.end()) {
st.erase(st.find(++ right));
}
res = max(res, right - left + 1);
}
return res;
}
};
時間計算量はO(NlogN)のアイデアです。最初に並べ替えてから、トラバースして判断します。
- cntは、トラバーサルプロセスの各レコードの最長の連続シーケンス長を記録するために使用され、resは、最終結果の最長の連続シーケンス長を記録するために使用されます。
- num [i] == num [i-1]の場合、スキップして次の判断を続けます
- num [i] == num [i-1] + 1の場合、res ++
- それ以外の場合、res = max(res、cnt)、およびcnt = 1のカウントを再開します
class Solution {
public:
int longestConsecutive(vector<int>& num) {
int size = num.size();
if(size <= 1) return size;
sort(num.begin(), num.end());
int cnt(1), res(1);
for(int i = 1; i < size; i ++) {
if(num[i] == num[i - 1]) {
continue;
} else if(num[i] == num[i - 1] + 1) {
cnt ++;
} else {
res = max(res, cnt);
cnt = 1;
}
}
res = max(res, cnt);
return res;
}
};