LeetCode --- 416周赛

题目列表

3295. 举报垃圾信息

3296. 移山所需的最少秒数

3297. 统计重新排列后包含另一个字符串的子字符串数目 I

3298. 统计重新排列后包含另一个字符串的子字符串数目 II

一、举报垃圾信息

直接用哈希表统计bannedWords中的单词,遍历message中出现的垃圾信息个数即可,代码如下

cpp 复制代码
class Solution {
public:
    bool reportSpam(vector<string>& message, vector<string>& bannedWords) {
        unordered_set<string> st(bannedWords.begin(),bannedWords.end());
        int ans = 0;
        for(auto& s:message){
            if(st.count(s)){
                if(++ans > 1)
                    return true;
            }
        }
        return false;
    }
};

二、移山所需要的最少秒数

这题的关键在于工人是同时开始工作的,也就是说,只要给定了一个时间,那么我们就能算出所有工人的降低的山的高度,从而来判断是否能将山的高度降为0,并且工作时间越长,山的高度被降为0的可能性越大,具有单调性,可以用二分来做。那么如何根据所给的时间来快速算出每个工人降低山的高度呢?假设降低的山的高度为 x,工人的基础工作时间为 t,给定的时间为 k,则有 1t+2t+3t+...+xt <= k,化简得 (x+1)*x/2*t <= k,只要解这个一元二次方程即可,代码如下

cpp 复制代码
class Solution {
public:
    long long minNumberOfSeconds(int mountainHeight, vector<int>& workerTimes) {
        int n = workerTimes.size();
        auto check = [&](long long k)->bool{
            long long sum = 0;
            for(auto t:workerTimes){
                long long a = (sqrt(1 + 8.0*k/t) - 1) / 2.0;
                sum += a;
            }
            return sum >= mountainHeight;
        };
        int mx = ranges::max(workerTimes);
        int c = mountainHeight / n + 1; // 平均一个人需要降低的山的高度
        // 以工作时间最长的人完成工作的时间,作为所有人的工作上限时间
        long long l = 0, r = 1LL * (c + 1) * c / 2 * mx;
        while(l <= r){
            long long mid = l + (r - l)/2;
            if(check(mid)) r = mid - 1;
            else l = mid + 1;
        }
        return l;
    }
};

当然这题也可以用模拟来实现,代码如下

cpp 复制代码
class Solution {
    using LL = long long;
public:
    long long minNumberOfSeconds(int mountainHeight, vector<int>& workerTimes) {
        priority_queue<tuple<LL,LL,int>,vector<tuple<LL,LL,int>>,greater<>> pq;
        // 记录该工人完成目前工作的总时间,当前工人降低山的高度需要的工作时间,基础工作时间
        for(auto t:workerTimes){
            pq.emplace(t,t,t); 
        }
        LL ans = 0;
        while(mountainHeight--){
            auto [cur, inc, base] = pq.top(); pq.pop();
            ans = cur;
            pq.emplace(cur + inc + base, inc + base, base);
        }
        return ans;
    }
};

三、统计重新排列后包含另一个字符串的子字符串数目I & II

思路如下

  1. 由于可以重新排列,所以我们并不关心字符的顺序,只关心它出现的次数,
  2. 统计子字符串的数目,一般的思路就是枚举右端点,统计有几个符合条件的左端点 / 枚举左端点,统计有几个符合条件的右端点。
  3. 根据第二点,如果枚举右端点 right,那么我们只要找到最靠近它的满足条件的左端点left,在left之前的所有下标都能作为左端点,即结果增加left+1
  4. 以right为右端点的满足条件的最短区间[left,right],会随着right的增加,而整体往右移,也就是是说left和right的变化具有单调性,对于这类区间的求解,我们可以使用滑动窗口

代码如下

cpp 复制代码
class Solution {
public:
    long long validSubstringCount(string word1, string word2) {
        long long ans = 0;
        int cnt[26]{};
        for(auto e:word2)
            cnt[e-'a']++;
        int sum = word2.size();
        int cnt1[26]{};
        for(int l = 0, r = 0; r < word1.size(); r++){
            int i = word1[r] - 'a';
            cnt1[i]++;
            if(cnt1[i] <= cnt[i]) sum--;
            while(sum == 0){
                i = word1[l] - 'a';
                if(--cnt1[i] < cnt[i])
                    sum++;
                l++;
            }
            ans += l;
        }
        return ans;
    }
};
相关推荐
故事和你9138 分钟前
sdut-程序设计基础Ⅰ-实验二选择结构(1-8)
大数据·开发语言·数据结构·c++·算法·优化·编译原理
努力学算法的蒟蒻44 分钟前
day106(3.7)——leetcode面试经典150
算法·leetcode·面试
Σίσυφος19001 小时前
PCL聚类 之 欧式聚类(最常用)
算法·机器学习·聚类
所谓伊人,在水一方3331 小时前
【Python数据科学实战之路】第12章 | 无监督学习算法实战:聚类与降维的奥秘
python·sql·学习·算法·信息可视化·聚类
像素猎人1 小时前
数据结构之顺序表的插入+删除+查找+修改操作【主函数一步一输出,代码更加清晰直观】
数据结构·c++·算法
季明洵2 小时前
二叉树的最小深度、完全二叉树的节点个数、平衡二叉树、路径总和、从中序与后序遍历序列构造二叉树
java·数据结构·算法·leetcode·二叉树
想进个大厂2 小时前
代码随想录day63 64 65 66 图论08 09 10 11
c++·算法·图论
云泽8082 小时前
蓝桥杯算法精讲:双指针算法四大经典例题深度剖析
算法·职场和发展·蓝桥杯
小龙报2 小时前
【算法通关指南:算法基础篇】二分算法: 1.A-B 数对 2.烦恼的高考志愿
c语言·开发语言·数据结构·c++·vscode·算法·二分
yong99902 小时前
NNDA、PDA、JPDA、IMM数据关联算法MATLAB实现
开发语言·算法·matlab