zoukankan      html  css  js  c++  java
  • [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 };
  • 相关阅读:
    MySQL++:MySQL 复合索引、普通索引总结
    AutoCAD 二次开发之python(学习中)
    APScheduler 学习笔记
    pylint 定制化配置/使用 -待整理
    JDK和CGLIB动态代理区别
    Java 类加载过程
    判断字符串是否是数字类型
    Java 并发编程锁工具
    花式写挂
    WC2021 题目清单
  • 原文地址:https://www.cnblogs.com/zhizhiyu/p/10181635.html
Copyright © 2011-2022 走看看