leetcode每日一题(昨天的) -- 3356. 零数组变换 II

思路

这道题在昨天的基础上增加了val这个字段,并且要求出最小的k

  • 说实话,我这里其实没什么思路,甚至一开始都没咋看懂题,总之下面的思路是根据评论区大佬给出的代码得到的

题意说,要从前到后依次使用queries里的数组,直到可以使nums变为零数组

  • 如果直接按照题意遍历,时间复杂度很高
  • 而"依次"就代表数组是有顺序的,那么就可以用二分法优化 -- 也就是把queries进行二分,得到的mid就是k,然后去判断是否可以满足要求

二分

区间收缩 -- 满足要求,往左找(找到最小的k) ; 不满足往右找(区间更多,更有可能使nums变为零数组)

但是,这个由二分得到的k,究竟代表使用 0~(k-1)范围内的区间 还是 0~k呢?

  • 如果是0~(k-1),那么当二分右边界不断逼近queries.size()-1时,永远也拿不到最后一个区间
  • 所以必须得是0~k,这样mid=queries.size()-1时就代表使用了全部的区间

为什么这里使用**<=**作为二分循环条件呢?

  • 因为这里是要查找目标值是否存在以及存在的位置,需要处理left==right的情况

查分数组

这里判断的逻辑依然使用差分数组

  • 但不同的是,这里对于区间边界的处理是 -- 左区间减,(右区间+1)加
  • 因为这里最终判断条件 是 当nums[i]+diff[i] <= 0 ,代表当前位可以被减为0
  • 那么这里的diff[i]为负数时更为合适

当然,以上只是我的个人想法,不代表完全正确,大家可以酌情参考

代码

cpp 复制代码
class Solution {
public:
    int minZeroArray(vector<int>& nums, vector<vector<int>>& queries) {
        int n = nums.size();
        vector<int> diff(n + 1, 0);
        if (*(max_element(nums.begin(), nums.end())) == 0) {
            return 0;
        }

        auto check = [&](int k) -> bool {
            fill(diff.begin(), diff.end(), 0);
            // 检查使用前 k 个操作能否让所有 nums[i] <= 0
            for (int i = 0; i <= k; ++i) {
                int l = queries[i][0], r = queries[i][1], val = queries[i][2];
                diff[l] -= val;
                diff[r + 1] += val;
            }
            int sum = 0;
            for (int i = 0; i < n; ++i) {
                sum += diff[i];
                if (nums[i] + sum > 0) {
                    return false;
                }
            }
            return true;
        };

        // 二分查找最小满足条件的 k
        int left = 0, right = queries.size() - 1, res = -1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            // 如果这里的mid代表[前mid个数组],也就是0~(mid-1)这个范围内的数组,那么逼近右边时最多mid=size-1,会漏掉最后一个区间
            // 所以得代表0~mid这个范围内,也就是一共mid+1个
            if (check(mid)) {
                res = mid + 1;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }

        return res == -1 ? -1 : res;
    }
};
相关推荐
麦兜*21 分钟前
大模型时代,Transformer 架构中的核心注意力机制算法详解与优化实践
jvm·后端·深度学习·算法·spring·spring cloud·transformer
coding随想27 分钟前
算法界的“达摩克利斯之剑”——NP完全性理论
算法
秋难降1 小时前
栈:从基础概念到实战解题(详细)
数据结构·算法·排序算法
归云鹤1 小时前
QT信号和槽怎么传输自己定义的数据结构
开发语言·数据结构·qt
ezl1fe2 小时前
RAG 每日一技(十):向量检索的“死穴”?用混合搜索(Hybrid Search)来拯救!
后端·算法
Ahu_iii2 小时前
【图论基础】理解图的“闭环”:Tarjan 强连通分量算法全解析
算法·图论
PixelMind2 小时前
【IQA技术专题】DISTS代码讲解
图像处理·人工智能·python·算法·iqa
项目申报小狂人2 小时前
2025年1中科院1区顶刊SCI-投影迭代优化算法Projection Iterative Methods-附完整Matlab免费代码
开发语言·算法·matlab
AI 嗯啦2 小时前
机械学习--逻辑回归
算法·机器学习·逻辑回归
山烛2 小时前
逻辑回归详解:从数学原理到实际应用
python·算法·机器学习·逻辑回归