Article / 文章

LeetCode 第370题:区间加法

假设你有一个长度为 n 的数组,初始情况下所有的数字均为 0,你将会被给出 k 个更新的操作。 其中,每个操作会被表示为一个三元组:[startIndex, endIndex, inc],你需要将子数组 A[startIndex ... endIndex](包括 startIndex 和 endIndex)增加 inc。 请你返回 k 次操作后的数组。

📖 文章摘要

本文详细解析LeetCode第370题“区间加法”,这是一道差分数组问题。文章提供了基于差分数组的解法,包含C#、Python、C++三种语言实现,配有详细的算法分析和性能对比。适合想要提升数组操作能力的读者。

核心知识点: 差分数组、前缀和、区间操作 难度等级: 中等 推荐人群: 具有基础算法知识,想要提升数组操作能力的程序员

题目描述

假设你有一个长度为 n 的数组,初始情况下所有的数字均为 0,你将会被给出 k 个更新的操作。

其中,每个操作会被表示为一个三元组:[startIndex, endIndex, inc],你需要将子数组 A[startIndex … endIndex](包括 startIndex 和 endIndex)增加 inc。

请你返回 k 次操作后的数组。

示例

示例 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]

提示

  • 1 <= length <= 10^5
  • 0 <= updates.length <= 10^4
  • 0 <= updates[i][0] <= updates[i][1] < length
  • -1000 <= updates[i][2] <= 1000

解题思路

本题可以使用差分数组解决:

  1. 创建差分数组
  2. 对每个操作,在差分数组的start位置加inc,在end+1位置减inc
  3. 对差分数组求前缀和得到结果

时间复杂度: O(n + k),其中n是数组长度,k是操作次数 空间复杂度: O(n)

🎯 算法流程演示

算法流程演示

图解思路

差分数组操作

步骤 操作 差分数组 说明
初始 - [0,0,0,0,0] 初始状态
1 [1,3,2] [0,2,0,0,-2] 1位置+2,4位置-2
2 [2,4,3] [0,2,3,0,-5] 2位置+3,5位置-3
3 [0,2,-2] [-2,2,3,0,-5] 0位置-2,3位置+2

前缀和计算

步骤 当前值 前缀和 结果
1 -2 -2 -2
2 2 0 0
3 3 3 3
4 0 3 5
5 -5 -2 3

代码实现

C# 实现

public class Solution {
    public int[] GetModifiedArray(int length, int[][] updates) {
        int[] diff = new int[length];
        
        foreach (var update in updates) {
            int start = update[0];
            int end = update[1];
            int inc = update[2];
            
            diff[start] += inc;
            if (end + 1 < length) {
                diff[end + 1] -= inc;
            }
        }
        
        int[] result = new int[length];
        result[0] = diff[0];
        for (int i = 1; i < length; i++) {
            result[i] = result[i - 1] + diff[i];
        }
        
        return result;
    }
}

Python 实现

class Solution:
    def getModifiedArray(self, length: int, updates: List[List[int]]) -> List[int]:
        diff = [0] * length
        
        for start, end, inc in updates:
            diff[start] += inc
            if end + 1 < length:
                diff[end + 1] -= inc
                
        result = [0] * length
        result[0] = diff[0]
        for i in range(1, length):
            result[i] = result[i - 1] + diff[i]
            
        return result

C++ 实现

class Solution {
public:
    vector<int> getModifiedArray(int length, vector<vector<int>>& updates) {
        vector<int> diff(length, 0);
        
        for (const auto& update : updates) {
            int start = update[0];
            int end = update[1];
            int inc = update[2];
            
            diff[start] += inc;
            if (end + 1 < length) {
                diff[end + 1] -= inc;
            }
        }
        
        vector<int> result(length);
        result[0] = diff[0];
        for (int i = 1; i < length; i++) {
            result[i] = result[i - 1] + diff[i];
        }
        
        return result;
    }
};

执行结果

C# 实现

  • 执行用时:92 ms
  • 内存消耗:24.8 MB

Python 实现

  • 执行用时:28 ms
  • 内存消耗:14.2 MB

C++ 实现

  • 执行用时:4 ms
  • 内存消耗:8.4 MB

性能对比

语言 执行用时 内存消耗 特点
C++ 4 ms 8.4 MB 执行效率最高,内存占用最小
Python 28 ms 14.2 MB 代码简洁,内存占用适中
C# 92 ms 24.8 MB 类型安全,内存占用较大

代码亮点

  1. 🎯 使用差分数组优化区间操作
  2. 💡 处理边界情况
  3. 🔍 优化空间复杂度
  4. 🎨 代码结构清晰,易于维护

常见错误分析

  1. 🚫 未处理边界情况
  2. 🚫 数组越界
  3. 🚫 内存泄漏
  4. 🚫 时间复杂度过高

解法对比

解法 时间复杂度 空间复杂度 优点 缺点
差分数组 O(n + k) O(n) 高效,实现简单 需要额外空间
暴力 O(nk) O(1) 空间效率高 时间复杂度高

相关题目


📖 系列导航

🔥 算法专题合集 - 查看完整合集

📢 关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新第370题。


💬 互动交流

感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。

如果这篇文章对你有帮助,请:

  • 👍 点个赞,让更多人看到这篇文章
  • 📁 收藏文章,方便后续查阅复习
  • 🔔 关注作者,获取更多高质量算法题解
  • 💭 评论区留言,分享你的解题思路或提出疑问

你的支持是我持续分享的动力!

💡 一起进步:算法学习路上不孤单,欢迎一起交流学习!