• 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) -> 8
    说明:
    
    数组仅可以在 update 函数下进行修改。
    你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。

    算法1
    区间求和 自然使用 线段树 或者线段数组
    这里以线段树为例
    以 空间换时间 记录线段之间的和 最大最小值等
    由于是树 即使其中一部分元素改变或者某一个元素改变 更改记录也只是log(n)的复杂度

    class SegmentTreeNode {
    public:
        SegmentTreeNode(int start,int end,int sum,
            SegmentTreeNode* left = nullptr,
            SegmentTreeNode* right = nullptr):
            start(start),
            end(end),
            sum(sum),
            left(left),
            right(right){}
        SegmentTreeNode(const SegmentTreeNode&) = delete;
        SegmentTreeNode& operator=(const SegmentTreeNode&) = delete;
        ~SegmentTreeNode() {
            delete left;
            delete right;
            left = right = nullptr;
        }
    
    
        int start;
        int  end;
        int sum;
        SegmentTreeNode* left;
        SegmentTreeNode* right;
    };
    
    class NumArray {
    public:
        NumArray(vector<int> nums) {
            nums_.swap(nums);
            if (!nums_.empty())
                root_.reset(buildTree(0, nums_.size() - 1));
        }
    
        void update(int i, int val) {
            updateTree(root_.get(), i, val);
        }
    
        int sumRange(int i, int j) {
            return sumRange(root_.get(), i, j);
        }
    private:
        vector<int> nums_;
        std::unique_ptr<SegmentTreeNode> root_;
    
        SegmentTreeNode* buildTree(int start, int end) {
            if (start == end) {
                return new SegmentTreeNode(start, end, nums_[start]);
            }
            int mid = start + (end - start) / 2;
            auto left = buildTree(start, mid);
            auto right = buildTree(mid + 1, end);
            auto node = new SegmentTreeNode(start, end, left->sum + right->sum,
                left, right);
    
            return node;
        }
    
        void updateTree(SegmentTreeNode* root, int i, int val) {
            if (root->start == i && root->end == i) {
                root->sum = val;
                return;
            }
            int mid = root->start + (root->end - root->start) / 2;
            if (i <= mid) {
                updateTree(root->left, i, val);
            }
            else {
                updateTree(root->right, i, val);
            }
            root->sum = root->left->sum + root->right->sum;
        }
    
        int sumRange(SegmentTreeNode* root, int i, int j) {
            if (i == root->start && j == root->end) {
                return root->sum;
            }
            int mid = root->start + (root->end - root->start) / 2;
            if (j <= mid) {
                return sumRange(root->left, i, j);
            }
            else if (i > mid) {
                return sumRange(root->right, i, j);
            }
            else {
                return sumRange(root->left, i, mid) + sumRange(root->right, mid + 1, j);
            }
        }
    };
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Windows 平台下的Mysql集群主从复制
    IOS 的loadView 及使用loadView中初始化View注意的问题。(死循环并不可怕)
    【2013625】K2+SAP集成应用解决方案在线研讨会
    to_char 和 to_date 经验分享
    Java向Access插入数据
    spring Bean的生命周期管理
    [置顶] 30分钟,让你成为一个更好的程序员
    Spring框架中Bean的生命周期
    Box2D的相关知识
    第八周项目二
  • 原文地址:https://www.cnblogs.com/itdef/p/11968069.html
Copyright © 2020-2023  润新知