LeetCodeWeeklyContest-183

R a n k : 1678 / 3846 A C : 3 / 4 Rank:1678 / 3846 \quad AC:3/4 Rank:1678/3846AC:3/4

还是太菜啊…

题目:周赛184

5380. 数组中的字符串匹配

写了一个暴力的模式匹配,由于n=100数据范围很小,是可以过掉的。

class Solution {
public:
    vector<string> stringMatching(vector<string>& words) {
        int n = words.size();
        set<string> ress; vector<string> res;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                // pm
                string s1 = words[i], s2 = words[j];
                if(s1.length()<s2.length()) swap(s1,s2);
                int k1 = 0;
                for(;k1<=s1.length()-s2.length();k1++){
                    if(s1.substr(k1,s2.length())==s2){
                        ress.insert(s2); break;
                    }
                }
            }
        }
        set<string>::iterator it = ress.begin();
        while(it!=ress.end()) {
            res.push_back(*it);
            it++;
        }
        return res;
    }
};

时间复杂度: O ( k n 2 ) O(kn^2) O(kn2) 空间复杂度: O ( m ) O(m) O(m)

5381. 查询带键的排列

模拟

class Solution {
public:
    vector<int> processQueries(vector<int>& queries, int m) {
        vector<int> P(m),res;
        unordered_map<int,int> maps;
        for(int i=0;i<m;i++) P[i] = i+1,maps[i+1]= i;
        for(int i=0;i<queries.size();i++){
            int idx = maps[queries[i]];
            res.push_back(idx);
            int value = P[idx];
            for(int j=idx;j>0;j--){
                P[j] = P[j-1];
                maps[P[j]] = j;
            }
            P[0] = value;
            maps[value] = 0;
        }
        return res;
    }
};

q u e r i e s queries queries的大小为 n n n,每次 P P P数组平均移动 n / 2 n/2 n/2,时间复杂度 O ( n m ) O(nm) O(nm),空间复杂度: O ( n + m ) O(n+m) O(n+m)

1410. HTML 实体解析器

循环替换,记得指定开始匹配替换的位置,否则会超时。
有一个坑点,根据下面这两个case可以体会一下。
“&” -> “&” 一不小心结果就会变为"&"
“>” -> “>” 一不小心结果就会变为">"
所以可以把"&"最后替换,放到最后面

class Solution {
public:
    string entityParser(string text) {
        vector<string> fs = {""","'",">","<","⁄","&"},
        rs = {"\"","'",">","<","/","&"};
        for(int i=0;i<fs.size();i++){
            string::size_type x = text.find(fs[i]);
            while(x!=text.npos){
                text.replace(x,fs[i].length(),rs[i]);
                x = text.find(fs[i],x+rs[i].length()); // 从替换之后的位置再去查找
            }
        }
        return text;
    }
};

网上说,C++标准没有规定string的复杂度,一般来讲stl find函数是线性复杂度,平均下来是 O ( m + n ) O(m+n) O(m+n),其中n是文本长度,m是模式串的长度,replace的复杂度一般也是线性的,由于替换的字符串很小,为简化计算暂不考虑,假设最坏情况下全部可以替换,类似如下情况:

“&&&&&&&&&”

替换次数为 n / m n/m n/m,最坏情况的复杂度为: 6 ∑ i = 1 n / m n − m i + b = 6 ( n 2 / m + n ( b − 2 ) / 2 m − n 2 / 2 m ) 6\sum_{i=1}^{n/m} n-mi+b = 6(n^2/m+n(b-2)/2m-n^2/2m) 6i=1n/mnmi+b=6(n2/m+n(b2)/2mn2/2m),其中b为常数,由于 m < < n m<m<<n,所以最坏复杂度的数量级大致是 O ( n ) O(n) O(n),最好的情况是一次也没有替换,复杂度是 6 O ( n + m ) 6O(n+m) 6O(n+m),平均一下,复杂度为O(n)

5383. 给 N x 3 网格图涂色的方案数

参考:分两种情况考虑下一行(动规)
当时以为是个搜索,而且还看错题了…

typedef long long ll;
const int mod = 1e9+7;
class Solution {
public:
    int numOfWays(int n) {
        ll abc = 6, aba = 6,tmp = 0; 
        for(int i=1;i<n;i++){
            tmp = abc;
            abc = (abc*2+aba*2)%mod;
            aba = (tmp*2+aba*3)%mod;
        }
        return (int)(aba+abc)%mod;
    }
};

你可能感兴趣的:(Leetcode,leetcode,c++)