第 402 场 LeetCode 周赛题解

A 构成整天的下标对数目 I

计数:遍历 h o u r s hours hours ,记录 h o u r s [ i ] % 24 hours[i]\%24 hours[i]%24 的出现次数

cpp 复制代码
class Solution {
  public:
    long long countCompleteDayPairs(vector<int>& hours) {
        vector<int> cnt(24);
        long long res = 0;
        for (auto x : hours) {
            res += cnt[(24 - x % 24) % 24];
            cnt[x % 24]++;
        }
        return res;
    }
};

B 构成整天的下标对数目 II

计数:遍历 h o u r s hours hours ,记录 h o u r s [ i ] % 24 hours[i]\%24 hours[i]%24 的出现次数

cpp 复制代码
class Solution {
  public:
    long long countCompleteDayPairs(vector<int>& hours) {
        vector<int> cnt(24);
        long long res = 0;
        for (auto x : hours) {
            res += cnt[(24 - x % 24) % 24];
            cnt[x % 24]++;
        }
        return res;
    }
};

C 施咒的最大总伤害

动态规划:设 p [ i ] p[i] p[i] 为最大伤害值不超过 i i i 的最大伤害值之和

cpp 复制代码
class Solution {
  public:
    using ll = long long;
    long long maximumTotalDamage(vector<int>& power) {
        map<int, ll> s;
        for (auto x : power)
            s[x] += x;
        map<int, ll> p;
        for (auto it = s.begin(); it != s.end(); it++) {
            p[it->first] = it == s.begin() ? 0 : p[prev(it)->first];
            auto lb = s.lower_bound(it->first - 2);
            if (lb == s.begin())
                p[it->first] = max(p[it->first], it->second);
            else {
                p[it->first] = max(p[it->first], p[prev(lb)->first] + it->second);
            }
        }
        return p.rbegin()->second;
    }
};

D 数组中的峰值

树状数组:用树状数组维护前缀区间内的峰值元素数,对于更新 n u m s [ i n d e x ] nums[index] nums[index] 的操作,可能改变是否为峰值的位置有 i n d e x − 1 index-1 index−1 、 i n d e x index index 和 i n d e x + 1 index+1 index+1

cpp 复制代码
class Solution {
  public:
    vector<int> countOfPeaks(vector<int>& nums, vector<vector<int>>& queries) {
        int n = nums.size();
        BinaryIndexedTree bit(n);
        auto isval = [](int i, int j, int k) { return j > i && j > k; };
        for (int i = 1; i < n - 1; i++)
            if (isval(nums[i - 1], nums[i], nums[i + 1]))
                bit.add(i + 1, 1);//初始化
        vector<int> res;
        for (auto& qi : queries) {
            if (qi[0] == 1) {
                if (qi[2] - qi[1] + 1 > 2)
                    res.push_back(bit.query(qi[2]) - bit.query(qi[1] + 1));
                else
                    res.push_back(0);
            } else { // update
                int i = qi[1];
                int val = qi[2];
                if (i - 1 > 0) {//判断nums[i-1]是否改变峰值性
                    if (!isval(nums[i - 2], nums[i - 1], nums[i]) && isval(nums[i - 2], nums[i - 1], val))
                        bit.add(i - 1 + 1, 1);
                    else if (isval(nums[i - 2], nums[i - 1], nums[i]) && !isval(nums[i - 2], nums[i - 1], val))
                        bit.add(i - 1 + 1, -1);
                }
                if (i + 1 < n - 1) {//判断nums[i+1]是否改变峰值性
                    if (!isval(nums[i], nums[i + 1], nums[i + 2]) && isval(val, nums[i + 1], nums[i + 2]))
                        bit.add(i + 1 + 1, 1);
                    else if (isval(nums[i], nums[i + 1], nums[i + 2]) && !isval(val, nums[i + 1], nums[i + 2]))
                        bit.add(i + 1 + 1, -1);
                }
                if (i != 0 && i != n - 1) {//判断nums[i]是否改变峰值性
                    if (!isval(nums[i - 1], nums[i], nums[i + 1]) && isval(nums[i - 1], val, nums[i + 1]))
                        bit.add(i + 1, 1);
                    if (isval(nums[i - 1], nums[i], nums[i + 1]) && !isval(nums[i - 1], val, nums[i + 1]))
                        bit.add(i + 1, -1);
                }
                nums[i] = val;
            }
        }
        return res;
    }

    class BinaryIndexedTree {//树状数组模板
      public:
        int N;
        vector<int> a;

        BinaryIndexedTree(int n) {
            N = n;
            a = vector<int>(N + 1);
        }

        inline int lowbit(int x) {
            return x & -x;
        }

        void add(int loc, int val) { // li[loc]+=val;
            for (; loc <= N; loc += lowbit(loc))
                a[loc] += val;
        }

        int query(int loc) { // sum{li[k] | 1<=k<=loc}
            int res = 0;
            for (; loc > 0; loc -= lowbit(loc))
                res += a[loc];
            return res;
        }
    };
};
相关推荐
leoufung5 小时前
LeetCode 149: Max Points on a Line - 解题思路详解
算法·leetcode·职场和发展
样例过了就是过了5 小时前
LeetCode热题100 最长公共子序列
c++·算法·leetcode·动态规划
样例过了就是过了9 小时前
LeetCode热题 不同路径
c++·算法·leetcode·动态规划
Navigator_Z10 小时前
LeetCode //C - 1031. Maximum Sum of Two Non-Overlapping Subarrays
c语言·算法·leetcode
如何原谅奋力过但无声12 小时前
【灵神高频面试题合集01-03】相向双指针、滑动窗口
数据结构·python·算法·leetcode
leoufung12 小时前
LeetCode 42:接雨水 —— 从“矩形法”到双指针的完整思考过程
java·算法·leetcode
_日拱一卒13 小时前
LeetCode:543二叉树的直径
算法·leetcode·职场和发展
穿条秋裤到处跑13 小时前
每日一道leetcode(2026.04.28):获取单值网格的最小操作数
算法·leetcode·职场和发展
leoufung14 小时前
LeetCode 68. Text Justification 题解:贪心与实现细节
算法·leetcode·职场和发展
洛水水14 小时前
【力扣100题】17.K 个一组翻转链表
算法·leetcode·链表