LeetCode毎週156

LeetCode毎週156

5205 ユニーク出現

あなたの整数配列arrを与えるために、配列内の各番号の出現回数を数える助けてください。

各番号の出現回数が一意である場合、それはtrueを返し、そうでない場合はfalse。

例1:

入力:ARR = [1,2,2,1,1,3]
出力:真の
説明:このアレイでは、1は3回発生し、二人は二回、1が3回発生して発生しました。2つの数の出現数が同じではありません。

例2:

入力:ARR = [1,2]
出力:偽

例3:

入力:ARR = [-3,0,1、-3,1,1,1、 -3,10,0]
出力:真

ヒント:

1 <= arr.length <= 1000
-1000 <= ARR [I] <= 100

非常に簡単な質問とデータ範囲が非常に小さく、ノートの数の配列を直接使用が表示され、その後、再決意

int num[2001];
bool vised[2001];
class Solution {
public:
    bool uniqueOccurrences(vector<int>& arr)
    {
        memset(num,0,sizeof(num));
        memset(vised,0,sizeod(vised));
        int len=arr.size();
        for(int i=0;i<len;i++)
        {
            int tmp=arr[i];
            if(tmp<0)
            {
                tmp*=-1;
                tmp+=1000;
            }//将数字简单映射一下
            num[tmp]++;
            vised[tmp]=1;
        }
        for(int i=0;i<=2000;i++)
        {
            if(vised[i])
            {
                for(int j=0;j<=2000;j++)
                {
                    if(i!=j)
                    {
                        if(num[i]==num[j])
                        {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
};

5207 の文字列が同じであるように

あなたに同じ長さ、S、およびTの2つの文字列を与えます。

i番目の文字を必要としているi番目の文字をtに変更されるでS | S [I] - T [I] |差オーバーヘッド(コストはゼロであってもよい)のASCII値の、すなわち2つの文字絶対値。

文字列を変更するための最大の予算はmaxCostです。文字列を変換する際に、トータルコストが予算以下であるべきで、それはまた、形質転換された文字列が不完全であってもよいことを意味します。

あなたはsがトンで、それに対応する部分文字列に変換されたサブストリングができた場合は、変換することができる最大の長さが返されます。

いかなるストリングSは、対応するサブストリングに変換しなくてもよい場合、T 0が返されます。

例1:

入力:S = "ABCD"、T = "BCDF"、コスト= 3
出力:3の
説明: "ABC"のS "BCD"になることがあります。コストは3であり、最大長は3です。

この間隔は、一般的に接頭辞配列コストで満たされ、操作がより簡単にする私の文字の前にコスト(I)のオーバーヘッドを覚えているので、コスト(J + 1)-COST(i)は、このセクションi乃至jであることができますオーバーヘッド。最大のセクションの先頭へのポインタと同時に、コストがポインタを超えたときにあまりmaxCostまで進みます、

そして、常に行に複数の答えを更新し、最悪時間計算量はO(N ^ 2)ですが、データには、悪性腫瘍のようではありません。

long long cost[100001];
class Solution {
public:
    int equalSubstring(string s, string t, int maxCost)
    {
        memset(cost,0,sizeof(cost));
        int len=s.size();
        int maxlen=0;
        int pl=1;
        for(int i=0;i<len;i++)
        {
            cost[i+1]=abs(s[i]-t[i])+cost[i];
            if(cost[i+1]-cost[pl]<=maxCost)
            {
                maxlen=max(maxlen,i-pl+2);
            }
            else
            {
                while(cost[i+1]-cost[pl]>maxCost && pl<=i+1)
                {
                    pl++;
                }
            }
        }
        return maxlen;
    }
};

5206は、文字列IIに隣接するすべての重複したエントリを削除します

「K倍の重複を削除し、」左右が一緒に文字列を省略するように、k個の文字をsから均等に隣接し、を選択し、それらを削除し、文字列sあなたを与えます。

あなたは、このような削除操作は、これまでのところまで継続することはできませんよ無限に繰り返される必要があります。

あなたは、削除をすべて実行し、結果の文字列を返した後。

この質問への答えは一意であることが保証されています。

例1:

入力:S = "ABCD"、K = 2
出力: "ABCD"
説明:内容は削除されるべきではありません。

例2:

入力:S = "deeedbbcccbdaa"、K = 3
出力: "AA"
説明:
"ddbbbdaa"を与えるために、 "最も幅の広い"と"CCC"を削除
"BBB"を削除、 "dddaa"を与えるために
"を与えるために、最後の"DDD"を削除AA "

直接スタックに、各文字が文字の同じ数を記録しながら、アナログラインプッシュ操作に対応します。プッシュをkかどうかを確認する前にするたびに、それはそれは、スタックのKポップのトップの前になりそうです。それを書くのは少し難しいと思うことは困難ではありませんが。

stack<pair<char,int> > sta;
char tmp[100001];
class Solution {
public:
    string removeDuplicates(string s, int k)
    {
        for(auto i:s)//依次枚举s中的字符
        {
            if(sta.empty())
            {
                sta.push(make_pair(i,1));
            }
            else
            {
                pair<char,int> now=sta.top();
                if(now.first==i)
                {
                    sta.push(make_pair(i,sta.top().second+1));//相同则次数+1
                }
                else
                {
                    sta.push(make_pair(i,1));
                }
            }
            while(!sta.empty() && sta.top().second==k)//检查是否达到k次
            {
                for(int j=0;j<k;j++)
                {
                    sta.pop();
                }
            }
        }
        int num=sta.size();
        tmp[num]=0;
        for(int i=num-1;i>=0;i--)
        {
            tmp[i]=sta.top().first;
            sta.pop();
        }
        string ans(tmp);
        return ans;
    }
};

5208. 移動迷路の最小数を通ります

あなたは蛇の怒りの権利の一部を覚えていますか?

私たちは、それが二つのセルを取ることを意味し、蛇の長さは2であり、n×n個のグリッド上で、新たな迷路のマップを構築しました。ヘビ((0,0)及び(0,1))は左上隅から移動し始めます。私たちは、1障害物を表して、0で細胞を空にします。ヘビ迷路は((N-1、N-2)及び(N-1、N-1))右下隅に移動する必要があります。

それぞれの動きは、ヘビは次のように行くことができます:

障害物が存在しない場合は、右のいずれかのセルに移動します。そして、まだ体の垂直/水平状態を保ちます。
障害物、細胞の下方への移動がない場合。そして、まだ体の垂直/水平状態を保ちます。
それは水平状態にし、その2つのユニットの下に空である場合、それは時計回りに90度回転させます。蛇から((R、C)、( R、C + 1)) ((R、C)、(に移動させ R + 1、C))。
それがその直立状態にあり、右の2個のセルが空である場合は、90度反時計回りに回転されます。蛇から((R、C)、( R + 1、C)) に移動させる((R、C)、( R、C + 1))。

ヘビを移動させるのに必要な最小数は目的地に到着し返します。

あなたは目的地に到達できない場合は、-1を返します。

例1:

入力:グリッド= [0,0,0,0,0,1]、
[1,1,0,0,1,0]、
[0,0,0,0,1,1]、
[0、 0,1,0,1,0]、
[0,1,1,0,0,0]、
[0,1,1,0,0,0]
出力:11
説明:
可能な解決策[右、右、時計回りの回転、右、下、下、下、下、下、右、左回りに回転する]です。

グリッドではなく、BFSの最短経路がdpですが、多くのBFSと状態遷移のこの質問コードワード(DPもたくさん)の驚くべき量。

最小移動は尾に位置する表現する開始点からDP(I、J、K)を用い、動的プログラミングを考慮して作られた(I、j)はヘビ状態kと(0、水平ヘビを示し、蛇は、1垂直表します。)番号。飛行機の移動についての質問は非常に明確に書かれていますが、が、普通の人は、このヘビが翻訳できるとは思わないだろう。

蛇は左に動いているのでそして、その下に列挙するために残しました。ヘビ2X2グリッドを回転させながらは、それぞれ、転送する必要性を必要とするので、非2X2と2X2の場合。

int dp[101][101][2];
class Solution {
public:
    int minimumMoves(vector<vector<int>>& grid)
    {
        int n=grid.size();
        memset(dp,0x3f,sizeof(dp)); 
        dp[0][0][0]=0;//初始化除0,0,0的状态其它都是无限大(非法)
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(!grid[i][j])
                {
                    if(i+1<n && j+1<n && !grid[i+1][j] && !grid[i][j+1] && !grid[i+1][j+1])//先考虑2X2的情况
                    {
                        dp[i][j][0]=min(dp[i][j][0],dp[i][j][1]+1);
                        dp[i][j][1]=min(dp[i][j][1],dp[i][j][0]+1);
                        dp[i+1][j][0]=min(dp[i+1][j][0],dp[i][j][0]+1);
                        dp[i][j+1][1]=min(dp[i][j+1][1],dp[i][j][1]+1);
                    }
                    if(j+2<n && !grid[i][j+1] && !grid[i][j+2])
                    {
                        dp[i][j+1][0]=min(dp[i][j+1][0],dp[i][j][0]+1);
                    }
                    if(i+2<n && !grid[i+1][j] && !grid[i+2][j])
                    {
                        dp[i+1][j][1]=min(dp[i+1][j][1],dp[i][j][1]+1);
                    }
                }
            }
        }
        if(dp[n-1][n-2][0]==0x3f3f3f3f)//如果结果无限大则表示没法到达
        {
            return -1;
        }
        else
        {
            return dp[n-1][n-2][0];
        }
    }
};

ゲームのタイトルは、それは難しいですが、それは直接アウトタイプ、大きな価値のこのトピックではありません。

おすすめ

転載: www.cnblogs.com/Heizesi/p/11613688.html