【LeetCode刷题】NO.1

107 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

1.题目

303.区域和检索 - 数组不可变

给定一个整数数组  nums,处理以下类型的多个查询:

1.计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= right 实现 NumArray 类:

  • NumArray(int[] nums) 使用数组 nums 初始化对象
  • int sumRange(int i, int j) 返回数组 nums 中索引 left 和 right 之间的元素的总和 ,包含 left 和 right 两点(也就是 nums[left] + nums[left + 1] + ... + nums[right] ) 示例 1:
输入:
["NumArray", "sumRange", "sumRange", "sumRange"]
[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
输出:
[null, 1, -1, -3]
解释: 
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3)
numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) 
numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1))

提示:

  • 1 <= nums.length <= 104
  • -105 <= nums[i] <= 105
  • 0 <= i <= j < nums.length
  • 最多调用 104 次 sumRange 方法

二、思路分析:

  • 1.这道题主要考察一个数组内的规定索引之间的元素之和,如果采用常规的for循环解决问题当然能够解决,但是这样的事件复杂度就相对高很多,对于这类问题我们可以采用前缀和框架思路来做这道题,通过前缀和框架思路我们的时间复杂度可以减小到O(1).
  • 2.做这道题的时候要注意前缀和的数组怎么定义以及采用前缀和数组后返回结果的索引问题.
  • 3.这道题有2种解法,第一种就是暴力解法利用for循坏记录和值来求解,第二种就是利用前缀和数组来解决问题,这种问题一般采用前缀和框架解决,时间复杂度更小.

三、代码:

 * @param {number[]} nums
 */
var NumArray = function(nums) {
    let preSum = new Array(nums.length+1)
    preSum[0]=0
    for(let i=1 ; i<=nums.length ; i++){
        preSum[i] = preSum[i-1] + nums[i-1]
    }
    this.preSum = preSum
};

/** 
 * @param {number} left 
 * @param {number} right
 * @return {number}
 */
NumArray.prototype.sumRange = function(left, right) {
    return this.preSum[right+1] - this.preSum[left]
};

时间复杂度:O(1)

四、总结:

类似这种有规律的数组内部求和题目时,我们一般都是采用前缀和方式求解,就是需要注意前缀和数组内索引的值与原数组值的关系,是前i项还是包括了数组的i项,利用框架思路解题能够更好的求解类似问题。

注:作者本人的所有题目都是用JS编写代码,因为本人是一个小前端0.0