开启我的LeetCode刷题日记:307. 区域和检索 - 数组可修改

78 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

编程世界总是离不了算法

最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力

于是决定蹭着假期,加强算法和数据结构相关的知识

那怎么提升呢?

其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode刷题之旅

第一阶段目标是:200道,每天12

为了不乱,本系列文章目录分为三部分:

  1. 今日题目:xxx
  2. 我的思路
  3. 代码实现

今天题目:307. 区域和检索 - 数组可修改

给你一个数组 nums ,请你完成两类查询。

其中一类查询要求 更新 数组 nums 下标对应的值 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 ,其中 left <= right 实现 NumArray 类:

  • NumArray(int[] nums) 用整数数组 nums 初始化对象
  • void update(int index, int val) 将 nums[index] 的值 更新 为 val
  • int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], ..., nums[right])  

示例 1:

输入:
["NumArray", "sumRange", "update", "sumRange"]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
输出:
[null, 9, null, 8]

解释:
NumArray numArray = new NumArray([1, 3, 5]);
numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9
numArray.update(1, 2);   // nums = [1,2,5]
numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ra… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的思路

看代码题解的前提是知道什么是线段树,本题目解答就不放入图片了,就是树的每个节点包含了start,end 数组的区间,以及区间和 sum。还有left左节点,right右节点。

  • 首先定义一个TreeNode类,代码中定义的首字母小写了不过不影响
  • 然后分别定义NumArray类的方法,分别为生成线段树,也就是this.root = - this.buildTree(nums,0,nums.length-1)
  • 定义update更新方法
  • 定义sum求和方法

代码实现

class treeNode {
    constructor(start, end) {
        this.left = null
        this.right = null
        this.sum = null
        this.start = start
        this.end = end
    }
}

let root = null

/**
 * @param {number[]} nums
 */
var NumArray = function (nums) {
    this.root = this.buildTree(nums, 0, nums.length - 1)
    console.log(this.root.sum)
};

/**
 * @param {number} index
 * @param {number} val
 * @return {void}
 */
NumArray.prototype.update = function (index, val) {
    this.updateVal(this.root, index, val)
};

/**
 * @param {number} left
 * @param {number} right
 * @return {number}
 */
NumArray.prototype.sumRange = function (left, right) {
    return this.sum(this.root,left,right)
};
NumArray.prototype.buildTree = function (nums, start, end) {
    if (start > end) {
        return null
    } else if (start === end) {
        let node = new treeNode(start, end);
        node.sum = nums[start]
        return node
    } else {
        let node = new treeNode(start, end);
        let mid = start + (end - start) / 2
        mid = Math.floor(mid)
        node.left = this.buildTree(nums, start, mid)
        node.right = this.buildTree(nums, mid + 1, end)
        node.sum = node.left.sum + node.right.sum
        return node
    }
}
NumArray.prototype.updateVal = function (root, index, val) {
    if (root.start === root.end) {
        root.sum = val
        return
    } else {
        let mid = root.start + (root.end - root.start) / 2
        mid = Math.floor(mid)
        if (index <= mid) {
            this.updateVal(root.left, index, val)
        } else {
            this.updateVal(root.right, index, val)
        }
        root.sum = root.left.sum + root.right.sum
    }
}
NumArray.prototype.sum = function (root, left, right) {
    if (left === root.start && right === root.end) {
        return root.sum
    } else {
        let mid = root.start + (root.end - root.start) / 2
        mid = Math.floor(mid)
        if (right <= mid) {
            return this.sum(root.left,left,right)
        } else if (left > mid){
            return  this.sum(root.right,left,right)
        }else {
            return this.sum(root.left,left,mid) + this.sum(root.right,mid+1,right)
        }

    }
}

总结

实现方式其实有很多,这里仅供参考~

由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹