Leetcode 周賽184 題解

寫在前面

第二次ak,不容易,雖然還是相對較水的一次。

5380. 數組中的字符串匹配

給你一個字符串數組 words ,數組中的每個字符串都可以看作是一個單詞。請你按 任意 順序返回 words 中是其他單詞的子字符串的所有單詞。

如果你可以刪除 words[j] 最左側和/或最右側的若干字符得到 word[i] ,那麼字符串 words[i] 就是 words[j] 的一個子字符串。

示例 1:

輸入:words = [“mass”,“as”,“hero”,“superhero”]

輸出:[“as”,“hero”]

解釋:“as” 是 “mass” 的子字符串,“hero” 是 “superhero” 的子字符串。
[“hero”,“as”] 也是有效的答案。

提示:

1 <= words.length <= 100

1 <= words[i].length <= 30

words[i] 僅包含小寫英文字母。

題目數據 保證 每個 words[i] 都是獨一無二的。

解法:

暴力就行了,數據量很小。

代碼:

class Solution {
public:
    vector<string> stringMatching(vector<string>& a) {
        vector<string> res;
        if(a.empty()) return res;
        int l = a.size();
        for(int i=0; i<l; ++i){
            for(int j=0; j<l; ++j){
                if(i!=j && a[j].size()>a[i].size()){
                    auto pos = a[j].find(a[i]);
                    if(pos!=a[j].npos){
                        res.push_back(a[i]);
                        break;
                    }
                }
            }
        }
        return res;
    }
};
  1. 查詢帶鍵的排列

給你一個待查數組 queries ,數組中的元素爲 1 到 m 之間的正整數。 請你根據以下規則處理所有待查項 queries[i](從 i=0 到 i=queries.length-1):

  • 一開始,排列 P=[1,2,3,…,m]。
  • 對於當前的 i ,請你找出待查項 queries[i] 在排列 P 中的位置(下標從 0 開始),然後將其從原位置移動到排列 P 的起始位置(即下標爲 0 處)。注意, queries[i] 在 P 中的位置就是 queries[i] 的查詢結果。


    請你以數組形式返回待查數組  queries 的查詢結果。

示例 1:

輸入:queries = [3,1,2,1], m = 5

輸出:[2,1,2,1]

解釋:待查數組 queries 處理如下:

對於 i=0: queries[i]=3, P=[1,2,3,4,5], 3 在 P 中的位置是 2,接着我們把 3 移動到 P 的起始位置,得到 P=[3,1,2,4,5] 。

對於 i=1: queries[i]=1, P=[3,1,2,4,5], 1 在 P 中的位置是 1,接着我們把 1 移動到 P 的起始位置,得到 P=[1,3,2,4,5] 。

對於 i=2: queries[i]=2, P=[1,3,2,4,5], 2 在 P 中的位置是 2,接着我們把 2 移動到 P 的起始位置,得到 P=[2,1,3,4,5] 。

對於 i=3: queries[i]=1, P=[2,1,3,4,5], 1 在 P 中的位置是 1,接着我們把 1 移動到 P 的起始位置,得到 P=[1,2,3,4,5] 。

因此,返回的結果數組爲 [2,1,2,1] 。

提示:

1 <= m <= 10^3

1 <= queries.length <= m

1 <= queries[i] <= m

解法:

從m的範圍來看,n2的算法就可以通過了,模擬這個過程就是n2。

代碼:

class Solution {
public:
    vector<int> processQueries(vector<int>& a, int m) {
        vector<int> p(m+1,0);
        vector<int> res;
        if(a.empty()) return res;
        for(int i=0; i<m; ++i){
            p[i] = i+1;
        }
        for(int k=0; k<a.size(); ++k){
            int pos;
            for(pos = 0; pos<m; ++pos){
                if(p[pos]==a[k]){
                    break;
                }
            }
            res.push_back(pos);
            int tmp = p[pos];
            for(int i=pos; i>=1; --i){
                p[i] = p[i-1];
            }
            p[0] = tmp;
        }
        return res;
    }
};

編程最忌諱的其實就是大量的數組移動操作,那麼爲了減少這種操作,我們可以用map記錄數值對應的索引位置,然後修改索引就行了。

代碼:

class Solution {
public:
    vector<int> processQueries(vector<int>& queries, int m) {
        map<int,int> mp;
        for(int i=0; i<m; ++i){
            mp[i+1] = i;
        }
        vector<int> res;
        for(int i=0; i<queries.size(); ++i){
            int k = queries[i];
            res.push_back(mp[k]);
            for(auto& p : mp){
                if(p.second>=mp[k])
                    continue;
                ++p.second;
            }
            mp[k] = 0;
        }
        return res;
    }
};
  1. HTML 實體解析器

「HTML 實體解析器」 是一種特殊的解析器,它將 HTML 代碼作爲輸入,並用字符本身替換掉所有這些特殊的字符實體。

HTML 裏這些特殊字符和它們對應的字符實體包括:

雙引號:字符實體爲 " ,對應的字符是 " 。

單引號:字符實體爲 ’ ,對應的字符是 ’ 。

與符號:字符實體爲 & ,對應對的字符是 & 。

大於號:字符實體爲 > ,對應的字符是 > 。

小於號:字符實體爲 < ,對應的字符是 < 。

斜線號:字符實體爲 ⁄ ,對應的字符是 / 。

給你輸入字符串 text ,請你實現一個 HTML 實體解析器,返回解析器解析後的結果。

示例 1:

輸入:text = “& is an HTML entity but &ambassador; is not.”

輸出:"& is an HTML entity but &ambassador; is not."

解釋:解析器把字符實體 & 用 & 替換

解法:

字符串操作基本功考察咯,比賽的時候switch報了很奇怪的錯,只好改成一堆if。

代碼:

class Solution {
public:
    string entityParser(string s) {
        string res = "";
        if(s.empty())
            return res;
        int p = 0;
        while(p<s.length()){
            string tmp = "";
            if(s[p]=='&'){
                while(p<s.length()&&s[p]!=';'){
                    tmp+=s[p];
                    ++p;
                }
                if(p==s.length()){
                    res+=tmp;
                }
                else{
                    tmp+=s[p];
                    //cout<<tmp<<endl;
                    if(tmp=="&quot;"){
                            res+="\"";
                    }
                    else if(tmp=="&apos;"){
                            res+="\'";
                    }
                    else if(tmp=="&amp;"){
                            res+="&";
                    }
                    else if(tmp=="&gt;"){
                            res+=">";
                    }
                    else if(tmp=="&lt;"){
                            res+="<";
                    }
                    else if(tmp=="&frasl;"){
                            res+="/";
                    }
                    else{
                            res += tmp;
                    }
                }
            }
            else{
                res+=s[p];
            }
            ++p;
        }
        return res;
    }
};

5383. 給 N x 3 網格圖塗色的方案數

你有一個 n x 3 的網格圖 grid ,你需要用 紅,黃,綠 三種顏色之一給每一個格子上色,且確保相鄰格子顏色不同(也就是有相同水平邊或者垂直邊的格子顏色不同)。

給你網格圖的行數 n 。

請你返回給 grid 塗色的方案數。由於答案可能會非常大,請你返回答案對 10^9 + 7 取餘的結果。

提示:

n == grid.length

grid[i].length == 3

1 <= n <= 5000

解法:

這題纔是今天的重點,乍一看是一道數學題,實際上,他就是一道數學題。。。

至少我水平不濟,想不出什麼狀態壓縮dp,只好老老實實找規律。

其實我們可以發現,一行三個格子,有兩種情況:使用兩種顏色和使用三種顏色。

我們假設字母abc分別表示三種顏色,那麼就有以下的塗色方式:

兩種顏色:

  • aba
  • aca
  • bab
  • bcb
  • cac
  • cbc

三種顏色:

  • abc
  • acb
  • bca
  • bac
  • cab
  • cba

這時候我們考慮下一行,如果現在是兩種顏色(aba),那麼下一行可能的塗色方式:

  • bcb
  • bab
  • cac
  • bac
  • cab

如果現在是三種顏色(abc),那麼下一行可能的塗色方式:

  • bab
  • bcb
  • bca
  • cab

可以觀察到,如果上一行是兩種顏色,那麼下一行有5種塗色方式,包含2種兩色,3種三色;如果上一行是三種顏色,那麼下一行有4種塗色方式,包含2種兩色,2種三色。

這時候就可以發現遞推規律已經出來了,寫就行了。(其實這和狀態壓縮dp本質差不多)

代碼:

class Solution {
public:
    int numOfWays(int n) {
        long long a,b,c,d;
        a = 6;
        b = 6;
        long long mod = pow(10,9) + 7;
        if(n==0) return 0;
        if(n==1) return 12;
        for(int i=2; i<=n; ++i){
            c = a*3 + b*2;
            c %= mod;
            d = a*2 + b*2;
            d %= mod;
            a = c;
            b = d;
        }
        long long res = a + b;
        return res%mod;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章