美文网首页
LeetCode 152周赛

LeetCode 152周赛

作者: crishawy | 来源:发表于2019-10-07 17:26 被阅读0次

    1. 题目列表

    2. 质数排列

    求出1~n的所有质数个数m,返回质数间和非质数间的排列方案即m! \times (n-m)!

    代码:

    const int MOD = 1000000007;
    class Solution {
    public:
        int numPrimeArrangements(int n) {
            if (n == 1) return 1;
            int cnt = 0;
            for (int i = 2; i <= n; i++){
                bool flag = true;
                for (int k = 2; k <= sqrt(i); k++){
                    if (i % k == 0){
                        flag = false;
                        break;
                    }
                }
                if (flag) cnt++;
            }
            return fact(cnt) * fact(n - cnt) % MOD;
        }
        
        long long fact(long long n){
            if (n == 1) return 1;
            return (fact(n - 1) % MOD * n) % MOD;
        }
    };
    

    3. 健身计划评估

    模拟和。

    代码:

    class Solution {
    public:
        int dietPlanPerformance(vector<int>& calories, int k, int lower, int upper) {
            int res = 0, sum = 0;
            for (int i = 0; i + k - 1 < calories.size(); i++){
                if (i == 0){
                    for (int j = 0; j < k; j++)
                        sum += calories[j];
                }else{
                    sum = sum - calories[i - 1] + calories[i + k - 1];
                } 
                if (sum > upper) res += 1;
                    else if (sum < lower) res -= 1;
            }
            return res;
        }
    };
    

    4. 构建回文串检测

    问题的核心在于如何寻找一个序列中某一子序列中的长度为2的重复对的个数,一边query一边判断会超时 O(n * n)

    另一个思路是定义sum[i][j] 来记录字母i在s的前j个字符中出现的个数(前缀和),那么对于每一个query区间[L,R],每个字母出现的次数 = sum[i][R] - sum[i][L - 1],时间复杂度O(26 * n + n) = O(n)

    代码:

    class Solution {
    public:
        vector<bool> canMakePaliQueries(string s, vector<vector<int>>& queries) {
            int sum[30][100010];
            memset(sum, 0, sizeof(sum));
            for (int i = 0; i < 26; i++){
                int c = 0;
                for (int j = 0; j < s.length(); j++){
                    if (s[j] - 'a' == i){
                        c++;
                    }
                    sum[i][j] = c;
                }
            }
            vector<bool> res;
            for (int i = 0; i < queries.size(); i++){
                int L = queries[i][0];
                int R = queries[i][1];
                int K = queries[i][2];
                int cnt = 0;
                for (int j = 0; j < 26; j++){
                    int pairs = L ? sum[j][R] - sum[j][L - 1] : sum[j][R];
                    cnt += pairs / 2;
                }
                if ((R - L + 1) % 2 == 0){
                    if (cnt + K >= (R - L + 1) / 2) res.push_back(true);
                    else res.push_back(false);
                }else{
                    if (cnt + K >= (R - L) / 2) res.push_back(true);
                    else res.push_back(false);
                }
            }
            return res;
        }
    };
    

    5. 猜字谜

    暴力法O(n^2)超时。

    字符串hash:定义map记录每个word出现的次数,将每个word用二进制和唯一表示,并去除重复的字符。然后遍历puzzles[i]的所有可能key,注意此key一定包括puzzles[i][0]的key,所有可能的key可以使用DFS遍历其全排列,计算每个key下的word出现的次数和。

    代码:

    
    map<int, int> mp;
    void f(string s){
        // 排序去除重复的字符
        sort(s.begin(), s.end());
        int key = 0;
        for (int i = 0; i < s.length(); i++){
            if (i == 0 || s[i] != s[i - 1])
                key += (1 << s[i] - 'a'); // 1左移x位 = 2^x
        }
        mp[key]++;
        
    }
    
    void DFS(string s, int k, int key, int& cnt){
        if (k == s.length()){
            cnt += mp[key]; // mp的按key查找直接通过数组方式,找不到则为0
            return;
        }
        DFS(s, k + 1, key + (1 << s[k] - 'a'), cnt);
        DFS(s, k + 1, key, cnt);
    }
        
    class Solution {
    public:
        vector<int> findNumOfValidWords(vector<string>& words, vector<string>& puzzles) {
            vector<int> res;
            mp.clear();
            for (int i = 0;i < words.size(); i++)
                f(words[i]);
            for (int i = 0; i < puzzles.size(); i++){
                int cnt = 0;
                // 求puzzles[i][1] ~ puzzles[i][6]的全排列的key数
                // 注意:初始的key是puzzles[i]首字符的key,全排列串从puzzles[i][1]开始,因为一定要包含puzzles的首字符
                DFS(puzzles[i], 1, 1 << puzzles[i][0] - 'a', cnt);
                res.push_back(cnt);
            }
            return res;
        }
    };
    

    相关文章

      网友评论

          本文标题:LeetCode 152周赛

          本文链接:https://www.haomeiwen.com/subject/cuyqyctx.html