当前位置: 首页 > news >正文

【LeetCode 每日一题】3495. 使数组元素都变为零的最少操作次数

Problem: 3495. 使数组元素都变为零的最少操作次数

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(Q * log R_max)
    • 空间复杂度:O(1)

整体思路

这段代码旨在高效地处理一系列查询 queries。对于每个查询 [l, r],它需要计算一个特定的值,然后将所有查询的结果累加起来。问题的核心在于理解辅助函数 preSum(x) 的作用以及主函数中 Math.max((sum + 1) / 2, max) 这条计算公式的含义。

算法的整体思路可以分解为以下几个步骤:

  1. 定义“成本”函数 f(k)

    • 代码隐含地为每个正整数 k 定义了一个“成本”或“值”。这个成本由 preSum 函数的内部逻辑决定。
    • preSum 函数将正整数 1, 2, 3, ... 分成基于4的幂次的区间:
      • [1, 3] (即 [4^0, 4^1 - 1])
      • [4, 15] (即 [4^1, 4^2 - 1])
      • [16, 63] (即 [4^2, 4^3 - 1])
      • i 个区间是 [4^(i-1), 4^i - 1]
    • 所有落在第 i 个区间的整数 k,其“成本” f(k) 都被定义为 i
  2. 高效计算“成本”的前缀和

    • preSum(x) 函数的作用是计算从 1 到 x 所有整数的“成本”之和,即 Σ f(k) for k from 1 to x
    • 它通过 while 循环逐个处理上述的分层区间。在每次循环中,它计算出 [1, x] 范围内有多少个数(count)落在了当前处理的第 i 个区间,然后将 count * i 累加到总和 ans 中。这种分层累加的方法远比逐个计算 f(k) 要高效。
  3. 处理查询 [l, r]

    • minOperations 方法遍历每个查询。对于一个查询 [l, r]
      a. 计算区间总成本 sum:利用前缀和的思想,区间 [l, r] 的总成本可以通过 preSum(r) - preSum(l - 1) 快速计算得出。
      b. 计算区间最大成本 max:同样利用前缀和,区间内单个元素的最大成本必然是 f(r),因为成本函数 f(k) 是单调不减的。f(r) 的值可以通过 preSum(r) - preSum(r - 1) 计算出来。
      c. 应用特定公式:根据问题的具体要求(这通常与游戏理论或某种优化目标有关),将计算出的 summax 代入公式 Math.max((sum + 1) / 2, max) 来得到该查询的结果。(sum + 1) / 2 是一种计算 ceil(sum / 2.0) 的整数方法。
  4. 累加总结果

    • 将每个查询得到的结果累加到 ans 中,最终返回总和。

完整代码

class Solution {/*** 处理一系列查询,并返回结果的总和。* @param queries 一个二维数组,每个子数组 [l, r] 代表一个查询区间。* @return 所有查询结果的累加和。*/public long minOperations(int[][] queries) {long ans = 0;// 遍历每一个查询for (int[] query : queries) {int l = query[0];int r = query[1];// 使用 preSum 函数计算区间 [l, r] 内所有数字的“成本”总和。// 这是经典的前缀和用法。long sum = preSum(r) - preSum(l - 1);// 计算区间 [l, r] 内最大的单个“成本”。// 由于“成本”函数是单调不减的,所以最大成本就是 f(r)。long max = preSum(r) - preSum(r - 1);// 应用问题的特定公式来计算当前查询的结果。// (sum + 1) / 2 是 ceil(sum / 2.0) 的整数实现。ans += Math.max((sum + 1) / 2, max);}return ans;}/*** 计算从 1 到 x 的所有整数的“成本”之和。* “成本” f(k) = i,其中 4^(i-1) <= k < 4^i。* @param x 上限整数* @return 成本的前缀和*/private long preSum(int x) {// 如果 x 为 0 或负数,前缀和为 0if (x <= 0) return 0;long ans = 0; // 累加结果long p = 1;   // 当前处理区间的起始值,p = 4^(i-1)int i = 1;    // 当前处理区间的“成本”// 循环直到区间的起始值 p 超过 xwhile (p <= x) {// 计算 [1, x] 与当前成本区间 [p, 4*p - 1] 的交集中的元素数量。// Math.min(x, p * 4 - 1) 是交集的上界。long count = Math.min(x, p * 4 - 1) - p + 1;// 将这 count 个元素的总成本 (count * i) 累加到 ansans += count * i;// 移至下一个成本区间i++;p *= 4;}return ans;}
}

时空复杂度

时间复杂度:O(Q * log R_max)

  1. preSum(x) 函数分析

    • 该函数的核心是一个 while 循環。
    • 循环变量 p 每次迭代都乘以 4 (1, 4, 16, 64, ...)。这是一个指数级增长。
    • 因此,循环的次数与 log4(x) 成正比。
    • 所以,preSum(x) 函数的时间复杂度为 O(log x)
  2. minOperations 函数分析

    • 该函数的主体是一个 for 循环,它遍历所有的查询。设查询的数量为 Q
    • 在每次循环中,它会调用 preSum 函数三次。
    • 调用的参数最大为 r。设所有查询中 r 的最大值为 R_max
    • 那么,单次查询的处理时间为 3 * O(log R_max),即 O(log R_max)

综合分析
总的时间复杂度是 (查询数量) * (单次查询的时间),即 O(Q * log R_max)

空间复杂度:O(1)

  1. 存储分析
    • minOperations 函数和 preSum 函数在执行过程中都只使用了少数几个基本类型的变量(如 ans, l, r, sum, max, p, i, count)。
    • 这些变量的数量是固定的,不随查询数量 Q 或查询范围 R_max 的大小而改变。

综合分析
算法没有使用任何与输入规模成比例的额外数据结构。因此,其额外辅助空间复杂度为 O(1)

http://www.dtcms.com/a/390310.html

相关文章:

  • Part01、02 基础知识与编程环境、C++ 程序设计
  • C++聊天系统从零到一:brpc RPC框架篇
  • Java编程思想 Thinking in Java 学习笔记——第2章 一切都是对象
  • AssemblyScript 入门教程(2)AssemblyScript的技术解析与实践指南
  • 深入理解Java数据结构
  • 【试题】网络安全管理员考试题库
  • 第一章 信息化发展
  • 第六章:实用调试技巧
  • 人工智能通识与实践 - 智能语音技术
  • CSP-S 提高组初赛复习大纲
  • 卷积神经网络CNN-part7-批量规范化BatchNorm
  • [xboard]02 uboot下载、移植、编译概述
  • Python入门教程之字符串运算
  • 堡垒机部署
  • 刷题记录(10)stack和queue的简单应用
  • 如何进行时间管理?
  • Spring面试题及详细答案 125道(46-65) -- 事务管理
  • OA ⇄ CRM 单点登录(SSO)实现说明
  • 人工智能在设备管理软件中的应用
  • __pycache__ 文件夹作用
  • 利欧泵业数据中心液冷系统解决方案亮相2025 ODCC开放数据中心峰会
  • 【论文阅读】Masked Conditional Variational Autoencoders for Chromosome Straightening
  • 天气预测:AI 如何为我们 “算” 出未来的天空?
  • 大数据管理与应用有什么注意事项?企业该如何发挥大数据的价值
  • CSS的opacity 属性
  • STM32 LwIP协议栈优化:从TCP延迟10ms降至1ms的内存配置手册
  • 【0基础3ds Max】创建标准基本体(长方体、球体、圆柱体等)理论
  • 驾驭未来:深度体验 Flet 0.7.0 的重大变革与服务化架构
  • 【Datawhale组队学习202509】AI硬件与机器人大模型 task01 具身智能基础
  • Go语言高并发编程全面解析:从基础到高级实战