其他分享
首页 > 其他分享> > LeetCode第 80 场双周赛题解

LeetCode第 80 场双周赛题解

作者:互联网

LeetCode第 80 场双周赛题解

6095. 强密码检验器 II

题目描述:如果一个密码满足以下所有条件,我们称它是一个 强 密码:

给你一个字符串 password ,如果它是一个 强 密码,返回 true,否则返回 false

思路:根据题意模拟即可

时间复杂度:\(O(n)\),\(n\)为密码长度

参考代码:

class Solution {
public:
    bool strongPasswordCheckerII(string password) {
        if(password.size() < 8) return false;
        string s = "!@#$%^&*()-+";
        bool flag = false;
        for(auto c : password){
            for(auto ch : s){
                if(ch == c) flag = true;
            }
        }
        if(!flag) return false;
        flag = false;
        for(auto c : password){
            if(c >= '0' && c <= '9') flag = true;
        }
        if(!flag) return false;
        flag = false;
        for(auto c : password){
            if(c >= 'a' && c <= 'z') flag = true;
        }
        if(!flag) return false;
        flag = false;
        for(auto c : password){
            if(c >= 'A' && c <= 'Z') flag = true;
        }
        if(!flag) return false;
        for(int i = 1 ; i < password.size() ; ++i)
            if(password[i] == password[i - 1]) return false;
        return true;
    }
};

6096. 咒语和药水的成功对数

题目描述:给你两个数组\(a , b\)和一个整数\(s\),问对于每一个元素\(a_i\),有多少个\(1 \leq j \leq b.size()\)满足条件:\(a_i \times b_j \geq s\)。

思路:显然先将\(b\)数组从小到大,然后对于每一个\(a_i\),二分查找\(b\)数组中大于等于\(\frac{s + a_i - 1}{a_i}\)的最小元素下标,假设为\(idx\),则\(a_i\)对应的答案为\(b.size() - idx\)。

时间复杂度:\(O(nlogm + m logm)\),\(n , m\)分别为数组\(a , b\)的大小。

参考代码:

class Solution {
public:
    vector<int> successfulPairs(vector<int>& a, vector<int>& bb, long long success) {
        int m = bb.size();
        vector<long long>b(m);
        for(int i = 0 ; i < m ; ++i) b[i] = bb[i];
        sort(b.begin() , b.end());
        int n = a.size();
        vector<int>res(n , 0);
        for(int i = 0 ; i < n ; ++i){
            long long dx = (success + a[i] - 1) / a[i];
            res[i] = m - (lower_bound(b.begin() , b.end() , dx) - b.begin());
        }
        return res;
    }
};

6097. 替换字符后匹配

题目描述:给你两个字符串\(s , t\),然后给你一些替换规则,可以将\(t\)中的某个字符替换成规则中含有的另一个字符,但每一个字符最多替换一次,问是否存在替换方案使得字符串\(t\)成为\(s\)的子串。

思路:显然我们可以根据替换规则把\(t_0\)能匹配的位置求出来加一后放入集合\(a\)中,然后枚举\(t_1\)是否能与集合\(a\)中的下标所对应的字符匹配,若能匹配,则将该下标增加一后再次放入集合,依次类推。最后若集合为空则为false,否则为true

时间复杂度:\(O(nm)\),\(n , m\)分别是字符串\(s , t\)的长度。

参考代码:

class Solution {
public:
    bool matchReplacement(string s, string sub, vector<vector<char>>& mpp) {
        vector<vector<bool>>vis(300 , vector<bool>(300 , false));
        for(auto vec : mpp) vis[vec[0]][vec[1]] = true;
        int n = s.size() , m = sub.size();
        vector<int> a;
        for(int i = 0 ; i < n ; ++i){
            if(s[i] == sub[0] || vis[sub[0]][s[i]]) a.push_back(i + 1);
        }
        vector<int>b;
        for(int j = 1 ; j < m ; ++j){
            b.clear();
            for(auto val : a){
                if(s[val] == sub[j] || vis[sub[j]][s[val]]) b.push_back(val + 1);
            }
            a = b;
        }
        return a.size() > 0;
    }
};

6098. 统计得分小于 K 的子数组数目

题目描述:数组分数的定义为:\(s = (rs - lr + 1)\sum\limits_{ i = lr}^{rs}a_i\)。给你一个长度为\(n\)的数组\(a\)和一个整数\(k\),求其所有非空子数组中满足条件\(s < k\)的子数组数量。

思路:比较明显的双指针,考虑区间\([lr , rs]\),若该区间满足题设,那么以\(a_{rs}\)结尾的子数组对答案的贡献是\(rs - lr + 1\)。假设区间\([lr , rs]\)的和为\(sum\),当\(sum * (rs - lr + 1) \geq k\)时,移动\(lr\)直到不等式不成立为止。

时间复杂度:\(O(n)\)

参考代码:

class Solution {
public:
    long long countSubarrays(vector<int>& nums, long long k) {
        using ll = long long;
        ll res = 0, sum = 0;
        int lr = 0 , n = nums.size();
        for(int rs = 0 ; rs < n ; ++rs){
            sum += nums[rs];
            while((rs - lr + 1) * sum >= k) sum -= nums[lr++];
            if(lr <= rs) res += rs - lr + 1;
            //cout << res << " ";
        }
        //cout << endl;
        return res;
    }
};

标签:rs,int,题解,long,vector,lr,双周,80,size
来源: https://www.cnblogs.com/cherish-/p/16367667.html