第 400 场 LeetCode 周赛题解

A 候诊室中的最少椅子数

计数:记录室内顾客数,每次顾客进入时,计数器+1,顾客离开时,计数器-1

cpp 复制代码
class Solution {
  public:
    int minimumChairs(string s) {
        int res = 0;
        int cnt = 0;
        for (auto c : s) {
            if (c == 'E')
                res = max(res, ++cnt);
            else
                cnt--;
        }
        return res;
    }
};

B 无需开会的工作日

排序:将 m e e t i n g s meetings meetings 按开始时间升序排序(若开始时间相同,则按结束时间降序排序),这样使得存在重叠的一组会议在数组中是相邻的,然后遍历 m e e t i n g s meetings meetings 求各个不重叠会议时间段

cpp 复制代码
class Solution {
  public:
    int countDays(int days, vector<vector<int>>& meetings) {
        sort(meetings.begin(), meetings.end(), [](vector<int>& a, vector<int>& b) {
            if (a[0] != b[0])
                return a[0] < b[0];
            return a[1] > b[1];
        });
        int res = days;
        int n = meetings.size();
        for (int i = 0, j = 0; i < n; i = ++j) {
            int r = meetings[i][1];
            while (j + 1 < n && meetings[j + 1][0] <= r) {//求与meetings[i]重叠的一组会议
                r = max(r, meetings[++j][1]);
            }
            res -= r - meetings[i][0] + 1;//减去会议天数
        }
        return res;
    }
};

C 删除星号以后字典序最小的字符串

优先级队列:遇到 ∗ * ∗ 时,因为需删除该星号字符左边一个字典序最小的字符,且题目需最终剩余字符形成的字符串字典序最小,所以应该删除该星号字符左边下标最大的字典序最小的字符。用优先级队列维护当前还没删除的字符中的字典序最小的下标最大的字符

cpp 复制代码
class Solution {
  public:
    string clearStars(string s) {
        int n = s.size();
        priority_queue<pair<int, int>> heap;//最大堆
        vector<int> del(n);//删除标记
        for (int i = 0; i < n; i++) {
            if (s[i] != '*')
                heap.emplace('a' - s[i], i);
            else {
                auto [_, loc] = heap.top();
                heap.pop();
                del[loc] = 1;
            }
        }
        string res;
        for (int i = 0; i < n; i++) {
            if (s[i] != '*' && !del[i])
                res.push_back(s[i]);
        }
        return res;
    }
};

D 找到按位与最接近 K 的子数组

前缀和 + 二分:枚举子数组的左端点 i i i ,用二分求 l l l 使得 n u m s i & ⋯ & n u m s l numsi\&\cdots\&numsl numsi&⋯&numsl 为不小于 k k k 的最小值,若 l + 1 < n l+1<n l+1<n ,则 ∣ n u m s i & ⋯ & n u m s l + 1 − k ∣ |numsi\&\cdots\&numsl+1-k| ∣numsi&⋯&numsl+1−k∣ 也可能更新答案,二分过程中用前缀和来计算 n u m s i & ⋯ & n u m s m i d numsi\&\cdots\&numsmid numsi&⋯&numsmid 的值( n u m s i & ⋯ & n u m s m i d numsi\&\cdots\&numsmid numsi&⋯&numsmid 第 j j j 位为 1 1 1 当且仅当 n u m s i , ⋯   , n u m s m i d numsi,\cdots,numsmid numsi,⋯,numsmid 第 j j j 位都为 1 1 1)

cpp 复制代码
class Solution {
  public:
    int minimumDifference(vector<int>& nums, int k) {
        int n = nums.size();
        int ps[30][n + 1];//每一位的前缀和
        memset(ps, 0, sizeof(ps));
        for (int j = 0; j < 30; j++)
            for (int i = 0; i < n; i++)
                ps[j][i + 1] = nums[i] >> j & 1 ? ps[j][i] + 1 : ps[j][i];

        int res = INT32_MAX;
        for (int i = 0; i < n; i++) {
            int l = i, r = n - 1;
            while (l < r) {//二分求l
                int mid = (l + r + 1) / 2;
                int t = 0;
                for (int j = 0; j < 30; j++)
                    if (ps[j][mid + 1] - ps[j][i] == mid - i + 1)
                        t |= 1 << j;
                if (t >= k)
                    l = mid;
                else
                    r = mid - 1;
            }
            int t = 0;
            for (int j = 0; j < 30; j++)
                if (ps[j][l + 1] - ps[j][i] == l - i + 1)
                    t |= 1 << j;
            res = min(res, abs(t - k));
            if (t > k && l + 1 < n)
                res = min(res, abs((t & nums[l + 1]) - k));
        }
        return res;
    }
};
相关推荐
aqiu1111112 天前
【算法刷题】蓝桥杯/AtCoder:删除元素后的中位数问题(Symmetry / Median)
算法·蓝桥杯·排序·中位数
aqiu1111114 天前
【算法刷题】蓝桥杯:0星际争霸(大数比较 + 多关键字自定义排序)
算法·排序·自定义排序
OuO-26 天前
笔试强训 Day 44:最小差值、kotori 和素因子、dd 爱科学 1.0
二分查找·动态规划·贪心·模拟·记忆化搜索·递归·状态表示优化
oier_Asad.Chen8 天前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
aqiu1111118 天前
【算法刷题】蓝桥杯:怎么倒茶(贪心算法 + 结构体排序)
贪心·排序
OuO-28 天前
笔试强训 Day 43:kotori 和抽卡(二)、ruby 和薯条、循环汉诺塔
数学·前缀和·二分查找·动态规划·排序·滑动窗口·循环汉诺塔
Tisfy13 天前
LeetCode 3731.找出缺失的元素:哈希 / 排序
算法·leetcode·哈希算法·排序·哈希表
wabs66614 天前
关于图论【最短路径之Dijkstra算法(堆优化版)|卡码网47.参加科学大会的思考】
数据结构·算法·图论·优先级队列·邻接表·小顶堆·卡码网
Tisfy22 天前
LeetCode 3016.输入单词需要的最少按键次数 II:排序(贪心)
linux·算法·leetcode·题解·贪心·排序·计数
Tisfy23 天前
LeetCode 3014.输入单词需要的最少按键次数 I:遍历 / if-else计算(比纯数学公式写起来麻烦但好想)
数学·算法·leetcode·字符串·题解·贪心