[Leetcode] 第307题 区域和检索-数组可修改

参考博客:(LeetCode 307) Range Sum Query - Mutable(Segment Tree)

一、题目描述

给定一个整数数组  nums,求出数组从索引 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。

update(i, val) 函数可以通过将下标为 的数值更新为 val,从而对数列进行修改。

示例:

Given nums = [1, 3, 5]

sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8

说明:

  1. 数组仅可以在 update 函数下进行修改。
  2. 你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。

二、题目解析

像连续区间动态更新和查询这种问题,常常用线段树,树状数组等方法

很强大!!值得记录!

三、AC代码

 1 class NumArray {
 2 public:
 3     NumArray(vector<int> nums) {
 4         root = buildTree(nums, 0, nums.size() - 1);
 5     }
 6
 7     void update(int i, int val) {
 8         update(root, i, val);
 9     }
10
11     int sumRange(int i, int j) {
12         return sumRange(root, i, j);
13     }
14 private:
15     struct SegmentNode {
16         int start;
17         int end;
18         int sum;
19         SegmentNode* left;
20         SegmentNode* right;
21         SegmentNode(int start, int end) :start(start), end(end), sum(0) {}
22     };
23     SegmentNode *root;
24     SegmentNode* buildTree(vector<int>&nums, int start, int end) {//构建树
25         if (end < start)return NULL;
26         SegmentNode *node = new SegmentNode(start, end);
27         if (start == end) {
28             node->sum = nums[start];
29             return node;
30         }
31         int mid = start + (end - start) / 2;
32         node->left = buildTree(nums, start, mid);
33         node->right = buildTree(nums, mid + 1, end);
34         node->sum = node->left->sum + node->right->sum;
35         return node;
36     }
37     void update(SegmentNode *node, int pos, int val) {
38         if (node->start == node->end&&node->start == pos) {//叶子节点
39             node->sum = val;
40             return;
41         }
42         if (pos<node->start || pos>node->end)return;
43         int mid = node->start + (node->end - node->start) / 2;
44         if (pos <= mid) {
45             update(node->left, pos, val);//划分区间的时候,mid划分在左边
46         }
47         else {
48             update(node->right, pos, val);
49         }
50         node->sum = node->left->sum + node->right->sum;//更新sum
51     }
52     int sumRange(SegmentNode *node, int start, int end) {
53         if (node->start == start&&node->end == end) {
54             return node->sum;
55         }
56         int mid = node->start + (node->end - node->start)/2;
57         if (end <= mid)return sumRange(node->left, start, end);//左子树中包含结果
58         if (start > mid)return sumRange(node->right, start, end);//右子树中包含结果,注意没有等号
59         else return sumRange(node->left, start, mid) + sumRange(node->right, mid + 1, end);
60     }
61 };

原文地址:https://www.cnblogs.com/zhizhiyu/p/10181635.html

时间: 2024-10-13 12:03:42

[Leetcode] 第307题 区域和检索-数组可修改的相关文章

307.区域与检索--数组可修改

区域与检索--数组可修改 线段树 参考 链接 代码 class NumArray { private ArrayList<Integer> sumSegmentTree; private int n; public NumArray(int[] nums) { n = nums.length; sumSegmentTree = new ArrayList<>(2 * n + 1); for (int i = 0; i < n; i++) { sumSegmentTree.ad

【leetcode 简单】 第七十九题 区域和检索 - 数组不可变

给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点. 示例: 给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange() sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3 说明: 你可以假设数组不可变. 会多次调用 sumRange 方法. class NumArray: def __init__(self, n

LeetCode 307. 区域和检索 - 数组可修改

地址 https://leetcode-cn.com/problems/range-sum-query-mutable/ 题目描述给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点. update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改. 示例: Given nums = [1, 3, 5] sumRange(0, 2) -> 9 update(1, 2) sumRange(0, 2)

领扣(LeetCode)二维区域和检索 个人题解

给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2). 上图子矩阵左上角 (row1, col1) = (2, 1) ,右下角(row2, col2) = (4, 3),该子矩形内元素的总和为 8. 示例: 给定 matrix = [ [3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7], [1, 0, 3, 0, 5] ] sumRegi

leetcode第26题:删除排序数组的重复项

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2. 你不需要考虑数组中超出新长度后面的元素.解题思路: 数组完成排序后,我们可以放置两个指针 ii 和 jj,其中 ii 是慢指针,而 jj 是快指针.只要 nums[i] = nums

【LeetCode每天一题】Single Number(数组中单独的数字)

Given a non-empty array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Example 1: Input: [2,2,1] Output:

leetcode第27题:删除vector数组的元素(array)

题目: Given an array and a value, remove all instances of that value in place and return the new length. The order of elements can be changed. It doesn't matter what you leave beyond the new length. 这个比较简单,掌握vector的用法即可. 1 int removeElement(vector<int>

[LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变

Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2). The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, co

[Leetcode]303.区域和检索

题目 1.区域和检索: 简单题,前缀和方法 乍一看就觉得应该用前缀和来做,一个数组多次查询. 实现方法: 新建一个private数组prefix_sum[i],用来存储nums前i个数组的和, 需要找区间和的时候直接通过prefix_sum[j]-prefix[i-1]即可得到从[i,j]区间的和,当i是0的时候需要特殊处理以防数组越界. 1 class NumArray { 2 public: 3 NumArray(vector<int> nums) { 4 prefix_sum.reser