LeetCodeコンテストの記録(週刊シングル182)

前に書く

週末のリートコードコンテストで質問を整理する。

週刊181

5368.配列からラッキーナンバーを見つける

整数の配列で、整数の出現頻度がその値と等しい場合、この整数を「ラッキーナンバー」と呼びます。

整数配列arrを与えます。そこからラッキーナンバーを見つけて返します。

配列に複数のラッキーナンバーがある場合は、最大のものを返します。

配列にラッキーナンバーがない場合は、-1が返されます。

例1:

入力:arr = [2,2,3,4]

出力:2

説明:値2の頻度も2であるため、配列内の唯一のラッキーな数値は2です。

解決策:暴力は終わりました、言うことは何もありません、

コード:

class Solution {
public:
    int findLucky(vector<int>& a) {
        if(a.empty()) return -1;
        vector<int> c(501,0);
        for(int i=0; i<a.size(); i++){
            c[a[i]]++;
        }
        int res = -1;
        for(int i=1; i<=500; i++){
            if(c[i]==i)
                res = i;
        }
        return res;
    }
};

5369.戦闘ユニットの数を数える

n人の兵士が並んでいた。各兵士には固有の評価があります。

3人の兵士ごとに1つの戦闘ユニットを形成できます。グループ化のルールは次のとおりです。

添え字がi、j、kの3人の兵士をチームから選択し、レーティングはレーティング[i]、レーティング[j]、レーティング[ k]

戦闘ユニットは次の条件を満たす必要があります:レーティング[i] <レーティング[j] <レーティング[k]またはレーティング[i]>レーティング[j]>レーティング[k]、ただし0 <= i <j <k <nして

ください上記の条件下で形成できる戦闘ユニットの数を返します。各兵士は複数の戦闘ユニットの一部になることができます。

例:

入力:評価= [2,5,3,4,1]

出力:3

説明:3つの戦闘ユニット(2,3,4)、(5,4,1)、(5,3、 1)。

暴力

ゲーム中の範囲を一目見ただけで200、このような小さな範囲はあなたを暴力的にする(霧)、トリプルループn ^ 3はタイムアウトしません、それは少し醜いです

コード:

class Solution {
public:
    int numTeams(vector<int>& a) {
        if(a.empty()||a.size()<=2) return 0;
        int res = 0;
        for(int x1 = 0; x1<a.size(); x1++){
            for(int x2=x1+1; x2<a.size(); x2++){
                for(int x3 = x2+1; x3<a.size(); x3++){
                    if(a[x1]<a[x2] && a[x2]<a[x3]){
                        ++res;
                    }
                    if(a[x1]>a[x2] && a[x2]>a[x3]){
                        ++res;
                    }
                }
            }
        }
        return res;
    }
};

統計学

実際、この戦闘ユニットは3人しかいないので簡略化できます。そのため、最初に中央の人を固定し、次に彼の左右の彼よりも大きい人と小さい人の数を数えることができます。構成できるユニットの数は次のとおりです。biggerl* smallr +大きい*小さい

コード:

class Solution {
public:
    int numTeams(vector<int>& a) {
        int l = a.size();
        if(l<3) return 0;
        int res = 0;
        for(int i=1; i<l-1; i++){
            int biggerl(0),smallerl(0),biggerr(0),smallerr(0);
            for(int j=0; j<i; j++){
                if(a[j]<a[i]){
                    smallerl++;
                }
                else{
                    biggerl++;
                }
            }
            for(int j=i+1; j<l; j++){
                if(a[j]<a[i]){
                    smallerr++;
                }
                else{
                    biggerr++;
                }
            }
            res += biggerl * smallerr + biggerr * smallerl;
        }
        return res;
    }
};

5370.地下鉄システムの設計

以下の3つのメソッドをサポートするUndergroundSystemクラスを実装してください

。1. IDがcheckIn(int id、string stationName、int t)である

乗客が、時刻tに地下鉄駅stationNameに入る

乗客は同時に1つの地下鉄駅にのみ出入りできます。

2. checkOut(int id、string stationName、int t)

番号がidである乗客は、時刻tに地下鉄駅stationNameを出発します。

3. getAverageTime(文字列startStation、文字列endStation) 

は、地下鉄駅startStationから地下鉄駅endStationまでに費やされた平均時間を返します。

平均時間で計算されたトリップには、startStationからendStationまでのすべてのトリップが含まれます。

getAverageTimeを呼び出すと、リクエストされたルートに少なくとも1つのルートが含まれます。

checkInおよびcheckOutへのすべての呼び出しは論理的であると想定できます。つまり、時刻t1に顧客が地下鉄の駅に到着した場合、顧客が出発する時刻t2はt2> t1を満たす必要があります。すべてのイベントは時系列で示されています。

解決策:

このデザインの問題は難しくありませんが、より複雑です。同じ名前の人が何度も乗り降りするため、駅名、人物のID、乗り降りの時間など、記録することがたくさんあります。車から降りたときの対応時間を記録する方法です。C++でのペアは非常に便利な構造です。次に、車から降りた後の記録として、@ Ikaguraギャングのアイデアを示します。開始ステーションと終了ステーションがキーとして結合されています、それで記録することは非常に便利です。

コード:

class UndergroundSystem {
private:
    unordered_map<int,pair<string,int>> record;//记录人的id和上车时间
    unordered_map<string,pair<int,int>> count;//记录下车后的时间
public:
    UndergroundSystem() {
        record.clear();
        count.clear();
    }
    
    void checkIn(int id, string stationName, int t) {
        record[id] = {stationName,t};//上车记录
    }
    
    void checkOut(int id, string stationName, int t) {
        string name = record[id].first + stationName;//拼接
        count[name].first += t - record[id].second;//记录
        count[name].second += 1;
    }
    
    double getAverageTime(string startStation, string endStation) {
        string name = startStation + endStation;
        return double(count[name].first)/double(count[name].second);
    }
};

/**
* Your UndergroundSystem object will be instantiated and called as such:
* UndergroundSystem* obj = new UndergroundSystem();
* obj->checkIn(id,stationName,t);
* obj->checkOut(id,stationName,t);
* double param_3 = obj->getAverageTime(startStation,endStation);
*/

5371.すべての適切な文字列を見つける

長さnの2つの文字列s1およびs2と、文字列evilを提供します。良い文字列の数を返してください。

適切な文字列の定義は次のとおりです。長さはn、辞書式順序はs1以上、辞書式順序はs2以下で、サブ文字列としてevilを含みません。

答えが非常に大きくなる可能性があるため、答えのペア10 ^ 9 + 7の結果を返してください

例1:

入力:n = 2、s1 = "aa"、s2 = "da"、evil = "b"

出力:51

説明: 'a'で始まる合計25の適切な文字列があります: "aa"、 " ac "、" ad "、...、" az "。「c」で始まる25の適切な文字列もあります:「ca」、「cc」、「cd」、...、「cz」。最後に、 'd'で始まる適切な文字列があります: "da"。

対決があり、解決策を読んでも理解できません。最近、Huaweiのテストバンクを学ぶのは時間がかかるので、それを調べてリンクを投げません。

https://leetcode-cn.com/problems/find-all-good-strings/solution/shu-wei-dp-kmpqian-zhui-shu-zu-java-by-henrylee4/

たれだけ。

元の記事を13件公開 27 件を獲得 2649件を表示

おすすめ

転載: blog.csdn.net/u011708337/article/details/105187268