[牛客0042-Leetcode]#Find#ArrayMediumlongest-consecutive-sequence

最長の連続シーケンス

タイトル説明

順序付けられていない整数型の配列が与えられた場合、連続する要素の最長シーケンスの長さを見つけます。
例:
指定された配列は[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的元素
  • この質問のアイデア:
    ハッシュテーブルを使用して、最初に番号をハッシュテーブルにマップし、次に番号ごとに、それを見つけた後に削除し、次に両側を同時に検索し、それがあれば削除しますそれを見つけ、最後に長さを見つけます。
    ハッシュテーブル検索は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;
        
    }
};

おすすめ

転載: blog.csdn.net/cys975900334/article/details/106669226