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

Swift 解法详解:LeetCode 370《区间加法》

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码拆解
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

在日常开发中,我们经常会遇到类似“批量修改区间”的场景,比如给一批用户的积分统一加值,或者对一个时间段的数据统一做调整。这类问题如果逐个处理,效率会非常低。LeetCode 370《区间加法》就是一个这样的模型:我们要对一个数组的区间进行多次加法操作,最后返回修改后的数组。

这道题其实是“差分数组”技巧的典型应用,非常适合拿来作为算法思路的积累。

描述

题目要求:

给你一个长度为 n 的数组,初始时所有元素都是 0。再给你一系列更新操作,每个操作由 [startIndex, endIndex, inc] 三个数构成,表示从下标 startIndexendIndex(包含两端)之间的所有元素都增加 inc

最终返回修改后的数组。

示例 1

输入: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]
输出: [-2,0,3,5,3]
解释: 
初始数组: [0,0,0,0,0]
更新 [1,3,2] -> [0,2,2,2,0]
更新 [2,4,3] -> [0,2,5,5,3]
更新 [0,2,-2] -> [-2,0,3,5,3]

题解答案

如果我们天真地写法,每次更新就对 [startIndex, endIndex] 之间的每个元素都加上 inc,那在最坏情况下时间复杂度会达到 O(k·n)k 是操作次数,n 是数组长度。这在数据量大的时候会非常慢。

正确的思路是用 差分数组(Difference Array)

  • 差分数组的本质是用一个辅助数组 diff 来记录“变化趋势”。

  • 当我们要对 [l, r] 区间加 inc 时,只需要:

    • diff[l] += inc
    • 如果 r + 1 < n,则 diff[r+1] -= inc
  • 最后通过一次前缀和,把 diff 还原成最终的数组。

这样每次操作只需要 O(1),最终再做一次前缀和 O(n) 就能得到答案。

题解代码分析

下面是 Swift 的完整代码实现:

import Foundationclass Solution {func getModifiedArray(_ length: Int, _ updates: [[Int]]) -> [Int] {var diff = Array(repeating: 0, count: length)// 应用差分更新for update in updates {let start = update[0]let end = update[1]let inc = update[2]diff[start] += incif end + 1 < length {diff[end + 1] -= inc}}// 通过前缀和恢复原数组var result = Array(repeating: 0, count: length)var runningSum = 0for i in 0..<length {runningSum += diff[i]result[i] = runningSum}return result}
}// MARK: - Demo 演示
let solution = Solution()
let length = 5
let updates = [[1,3,2],[2,4,3],[0,2,-2]]
let result = solution.getModifiedArray(length, updates)
print(result) // 输出: [-2, 0, 3, 5, 3]

代码拆解

  1. 初始化差分数组

    • diff 和原数组长度一样,初始全为 0。
    • 它不是最终结果,而是用来记录“区间的变化”。
  2. 应用更新

    • 每个更新 [l, r, inc] 只改动 diff[l]diff[r+1]
    • 这样就避免了对区间里所有元素逐个修改。
  3. 恢复结果

    • 最后用一个变量 runningSum 记录前缀和,逐步把 diff 变成最终结果。

示例测试及结果

运行上面的 Demo:

初始数组: [0,0,0,0,0]
更新 [1,3,2] -> [0,2,2,2,0]
更新 [2,4,3] -> [0,2,5,5,3]
更新 [0,2,-2] -> [-2,0,3,5,3]输出: [-2, 0, 3, 5, 3]

和题目给的结果完全一致。

时间复杂度

  • 更新阶段:每个操作只需要 O(1),k 次操作就是 O(k)
  • 恢复数组:前缀和需要 O(n)。
  • 总体复杂度:O(n + k)

这比逐个更新 O(n·k) 的复杂度要高效得多。

空间复杂度

  • 只用了一个和原数组等长的差分数组 diff,所以空间复杂度是 O(n)

总结

这道题本质上是考差分数组的应用,常见于 区间更新 的场景。

思路要点:

  • 直接更新区间效率低,要用“变化趋势”的方式去优化。
  • 差分数组的妙处在于只记录“区间开始变化”和“区间结束恢复”。
  • 最后一次性还原出结果,既高效又简洁。

在实际开发中,这种技巧同样很有用。比如:

  • 日志系统里批量修改某些时间段的计数。
  • 数据库里批量更新一批连续记录。
  • 游戏里给一群玩家(按等级区间)加经验值。

差分数组就是这类问题的通用解法,非常值得掌握。

http://www.xdnf.cn/news/1448299.html

相关文章:

  • 《网络安全实战:CC攻击(应用层)与DDoS攻击(网络层)的底层逻辑与防御体系》​
  • 分发饼干——很好的解释模板
  • 从“看见”到“行动”:一场机器视觉与机器人的软硬件共舞
  • 把本地win11系统打包成镜像并安装到vmware中
  • Springboot3+SpringSecurity6Oauth2+vue3前后端分离认证授权-授权服务
  • FastVLM:高效视觉编码助力视觉语言模型突破高分辨率效率瓶颈
  • LeNet-5:卷积神经网络的奠基之作
  • 0903 C++类的运算符重载、静态成员与继承
  • 前端-安装VueCLI
  • 【ARM嵌入式汇编基础】-数据处理指令(三)
  • OpenHarmony Ability“全家桶”彻底拆解:从UIAbility到ExtensionAbility一文说清楚
  • LeetCode 1537.最大得分
  • 残差连接的概念与作用
  • 蓝桥杯算法之基础知识(6)
  • Netty从0到1系列之Channel
  • 【 线段树】P12347 [蓝桥杯 2025 省 A 第二场] 栈与乘积|普及+
  • 基于 HTML、CSS 和 JavaScript 的智能图像灰度直方图分析系统
  • HTML全屏功能实现汇总
  • npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR!
  • 求单源最短路(Dijkstra 算法-迪杰斯特拉算法,SPFA)
  • 【Unity基础】两个关于UGUI中Text对非英文字体支持的问题
  • SpringAI应用开发面试全流程:技术原理、架构优化与企业场景解析
  • 复写零(双指针)
  • JavaScript学习最后一章节(小练习)
  • 如何解决虚拟机网络连接问题:配置固定 IP 篇
  • Spring Authorization Server 1.5.2 使用YML配置的方式,最常用法总结
  • 【算法--链表】141.环形链表(通俗讲解链表中是否有环)
  • 分布式AI算力系统番外篇-----超体的现世《星核》
  • 强化学习中的模仿学习是什么?
  • 相关性分析与常用相关系数