1480. 一维数组的动态和

234 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第28天,点击查看活动详情

题目 leetcode.cn/

  • 给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。
  • 请返回 nums 的动态和。

示例

  • 示例 1:

    • 输入: nums = [1,2,3,4]
    • 输出: [1,3,6,10]
    • 解释: 动态和计算过程为 [1, 1+2, 1+2+3, 1+2+3+4] 。
  • 示例 2:

    • 输入: nums = [1,1,1,1,1]
    • 输出: [1,2,3,4,5]
    • 解释: 动态和计算过程为 [1, 1+1, 1+1+1, 1+1+1+1, 1+1+1+1+1] 。
  • 示例 3:

    • 输入: nums = [3,1,2,10,1]
    • 输出: [3,4,6,16,17]

提示:

  • 1 <= nums.length <= 1000
  • -10^6 <= nums[i] <= 10^6

代码

function runningSum(nums: number[]): number[] {
    let result = new Array(nums.length);
    for(let i = 0; i < result.length; i++){
        let sum = 0;
        for(let k = 0; k <= i; k++){
            sum += nums[k];
        }
        result[i] = sum;
    }
    return result;
};
  • 暴力解法:
    • 按照题目给出的新数组的计算公式runningSum[i] = sum(nums[0]…nums[i])可知,新数组的第i项都是原数组的前i项的和
    • 因此初始化一个新数组,新数组的长度就是原数组的长度,可填充初始值,也可以不填充初始值
    • 首先遍历新数组,定义一个变量用来保存每次计算的原数组的和
    • 再遍历原数组,范围取决于要得到新数组的第几项的值,所以范围小于等于i,把原数组的前i项加起来,得到新数组的第i项的值,最后返回新数组
    • 使用了双重遍历,时间上开销较大,每次遍历都新定义变量,开辟了额外的空间内存
function runningSum(nums: number[]): number[] {
    let result = new Array(nums.length);
    result[0] = nums[0];
    for(let i = 1; i < result.length; i++){
        result[i] = result[i-1] + nums[i];
    }
    return result;
};
  • 改进版:
    • 仔细观察发现,新数组的第一项就是原数组的第一项,因为新数组的第i项都是原数组的前i项的和,当i = 0时,第一项永远相等。然后新数组的后面每一项的值,都是前一项的值加上原数组的当前i下标的值,这样省略了重复累加
    • 遍历数组,从新数组的下标为1开始,新数组的下标为i的值,等于下标为i - 1的值加上原数组下标为i的值
    • 只遍历了一次,节省了时间消耗
function runningSum(nums: number[]): number[] {
    for(let i = 1; i < nums.length; i++){
        nums[i] = nums[i - 1] + nums[i];
    }
    return nums;
};
  • 最终版:
    • 根据上面的思路,最后发现可以直接在原数组上面修改,直接从原数组的下标为1开始,后一项都是前一项加上当前项的值,nums[i] = nums[i - 1] + nums[i]。原地修改。也不用重新定义数组变量,节省了内存空间