一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
编程世界总是离不了算法
最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力
于是决定蹭着假期,加强算法和数据结构相关的知识
那怎么提升呢?
其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode
刷题之旅
第一阶段目标是:200
道,每天1
到2
篇
为了不乱,本系列文章目录分为三部分:
- 今日题目:xxx
- 我的思路
- 代码实现
今天题目: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)
}
}
}
总结
实现方式其实有很多,这里仅供参考~
由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹