Solution to the 278th weekly game of LeetCode

Posted by joeysarsenal on Sun, 30 Jan 2022 18:52:44 +0100

5993. Multiply the found value by 2

Title Description: give you an array \ (Num \) and an integer \ (x \). If \ (x \) is in the array, multiply \ (x \) by \ (2 \), otherwise return the value of \ (x \).

Idea: use map to store the values in the array, and then simulate according to the meaning of the question

Time complexity: \ (O(nlogn) \)

Reference code:

class Solution {
public:
    int findFinalValue(vector<int>& nums, int original) {
        map<int , int>mp;
        for(auto num : nums) mp[num] = 1;
        while(mp[original]) original <<= 1;
        return original;
    }
};

5981. All subscripts with the highest score in the group

Title Description: give you an array with only 01. Divide the array into two parts. The number of scores in the left part is 0, the number of scores in the right part is 1, and the grouping score is the sum of the scores in the left and right parts. Find all subscripts that make the grouping score the highest.

Idea: simple dp can be simulated according to the meaning of the topic.

Time complexity: \ (O(n) \)

Reference code:

class Solution {
public:
    vector<int> maxScoreIndices(vector<int>& nums) {
        int n = nums.size();
        vector<int>f(n + 1 , 0) , g(n + 2 , 0);
        for(int i = 1 ; i <= n ; ++i){
            f[i] = nums[i - 1] == 0;
            f[i] += f[i - 1];
        }
        for(int i = n ; i >= 1 ; --i){
            g[i] = nums[i - 1] == 1;
            g[i] += g[i + 1];
        }
        vector<int>res;
        int max = 0;
        for(int i = 1 ; i <= n + 1; ++i){
            if(f[i - 1] + g[i] < max) continue;
            if(f[i - 1] + g[i] == max) res.push_back(i - 1);
            else{
                max = f[i - 1] + g[i];
                res.clear();
                res.push_back(i - 1);
            }
        }
        return res;
    }
};

5994. Find the substring of the given hash value

Title Description: given a string \ (s \) with a length of \ (n \), find that all substrings with a length of \ (k \) meet the equation:

\[\sum\limits_{i = 1}^{k} t_i \times p^{i - 1} \% mod = hashValue \]

And the earliest substring appears. Where \ (t \) represents a substring with a length of \ (k \), and the integer value of the character \ (t_i \) is \ (t_i -'a '+ 1 \).

Idea:

The idea is: consider the following equation:

\[s_i*p^0 + s_{i + 1}*p^1 + ..+ s_{i + k - 1}*p^{k - 1}\\ = \frac{s_i*p^{i} + s_{i + 1}*p^{i + 1} + ..+ s_{i + k - 1}*p^{i + k - 1}}{b^{i}} \]

Then we can take \ (b^i *hashValue \) as the right side of the equation and check whether the left and right sides are equal when taking the module. However, there may be hash conflict when multiplying the denominator and then taking the module. It is safer to find the inverse element of \ (b^i \), but its inverse element may not exist. When I checked it to be equal, I substituted it for another check. The code is as follows:

class Solution {
public:
    string subStrHash(string s, int power, int mod, int k, int hashValue) {
        int n = s.size();
        vector<int>base(n + 1 , 0);
        base[0] = 1;
        vector<int>has(n + 1 , 0);
        for(int i = 1 ; i <= n ; ++i){
            has[i] = has[i - 1] + 1ll *(s[i - 1] - 'a' + 1) * base[i - 1] % mod;
            has[i] %= mod;
            base[i] = 1ll * base[i - 1] * power % mod;
        }
        //for(auto ha : has) cout << ha <<" " ;
        //cout << endl;
        for(int i = k ; i <= n; ++i){
            int dx = ((has[i] - has[i - k]) % mod + mod) % mod;
            int dy = 1ll * hashValue * base[i - k] % mod;
            if(dx == dy) {
                int tmp = 0, b = 1;
                for(int j = i - k ; j < i ; ++j){
                    tmp = tmp + 1ll * (s[j] - 'a' + 1) * b % mod;
                    tmp %= mod;
                    b = 1ll * b * power % mod;
                }
                if(tmp == hashValue) return s.substr(i - k , k);
            }
        }
        return "";
    }
};

The above code can be stuck out.

String Hash operation can Refer here

Later, consider the formula of string hash:

\[hash = \sum\limits_{i = 1}^{n} s_i * p^{n - i} \]

Let's transpose the string \ (s \), and the above formula becomes

\[hash = \sum\limits_{i = 1}^{n} t_i * p^{i - 1}\;\;t_i = s_{n - i + 1} \]

It is the same as the formula of the question, so you can transpose the string \ (s \), preprocess its string hash value, and then find the corresponding answer according to the value.

Time complexity: \ (O(n) \)

Reference code:

class Solution {
public:
    string subStrHash(string s, int power, int mod, int k, int hashValue) {
        reverse(s.begin() , s.end());
        int n = s.size();
        vector<int>base(n + 1 , 0),has(n + 1 , 0);
        base[0] = 1;
        for(int i = 1 ; i <= n ; ++i){
            has[i] = (1ll * has[i - 1] * power % mod + s[i - 1] - 'a' + 1) % mod;
            base[i] = 1ll * base[i - 1] * power % mod;
        }
        auto getHash = [&](int lr , int rs)->int{
            return ((has[rs] - 1ll * has[lr - 1] * base[rs - lr + 1] % mod)% mod + mod) % mod;
        };
        int idx = 0;
        for(int i = 1 ; i <= n - k + 1 ; ++i){
            if(getHash(i , i + k - 1) == hashValue) idx = i;
        }
        string res = s.substr(idx - 1 , k);
        reverse(res.begin() , res.end());
        return res;
    }
};

5995. String grouping

Title Description: look at the title yourself, although the Title Description reads strange.

Idea: considering that each character in each string can appear at most once, consider using an array to represent the string, such as string ab, which can be represented by 3. Then, each string is regarded as a point. We enumerate the points that can be generated according to the rules of the topic. If the enumerated points exist, then the connected blocks corresponding to the two points will be merged, so we need to use and search the set. The final answer is the number of connected blocks and the number of midpoint of the largest connected block. Note that the same string may exist and special judgment is required.

Time complexity: \ (O(26^2n)\) \(n \) is the number of strings.

Reference code:

class Solution {
public:
    vector<int> groupStrings(vector<string>& words) {
        int n = words.size();
        vector<int>p(n + 1 , 0) , cnt(n + 1 , 0);
        map<int , int>mp;
        for(int i = 1 ; i <= n ; ++i){
            p[i] = i;
            cnt[i] = 1;
        }
        auto find = [&] (auto find , int x)->int{
            if(x != p[x]) p[x] = find(find , p[x]);
            return p[x];
        };
        auto cal = [&](string& s)->int{
            int ans = 0;
            for(auto& c : s) ans |= 1 << (c - 'a');
            return ans;
        };
        auto solve = [&](int x, int idx)->void{
            if(mp.count(x) != 0){
                int u = find(find , mp[x]) , v = find(find , idx);
                p[u] = v;
                cnt[v] += cnt[u];
                return ;
            }
            mp[x] = idx;
            for(int i = 0 ; i < 26 ; ++i){
                int dy = x ^ (1 << i);
                if(mp.count(dy) == 0) continue;
                int u = find(find, mp[dy]) , v = find(find , idx);
                if(u == v) continue;
                p[u] = v;
                cnt[v] += cnt[u];
            }
            for(int i = 0 ; i < 26 ; ++i){
                if(((x >> i) & 1) == 0) continue;
                for(int j = 0 ; j < 26 ; ++j){
                    if((x >> j) & 1) continue;
                    int dy = x ^ (1 << i) ^ (1 << j);
                    if(mp.count(dy) == 0) continue;
                    int u = find(find , mp[dy]) , v = find(find , idx);
                    if(u == v) continue;
                    p[u] = v;
                    cnt[v] += cnt[u];
                }
            }
            return ;
        };
        for(int i = 1 ; i <= n ; ++i){
            int dx = cal(words[i - 1]);
            solve(dx , i);
        }
        vector<int>res(2 , 0);
        for(int i = 1 ; i <= n ; ++i){
            res[0] += p[i] == i;
            res[1] = max(res[1] , cnt[i]);
        }
        return res;
    }
};