参考博客:(LeetCode 307) Range Sum Query - Mutable(Segment Tree)
一、题目描述
给定一个整数数组 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) -> 8
说明:
- 数组仅可以在 update 函数下进行修改。
- 你可以假设 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