Leetcode307. Range Sum Query - Mutable区域和检索-数组可修改

1 篇文章 0 订阅
0 篇文章 0 订阅

给定一个整数数组  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

说明:

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

一般写法

class NumArray
{
    vector<int> nums;
    vector<int> temp;

  public:
    NumArray(vector<int> nums)
    {
        this->nums = nums;
        temp = nums;
        int val = 0;
        for (int i = 0; i < this->nums.size(); i++)
        {
            this->nums[i] = this->nums[i] + val;
            val = this->nums[i];
        }
    }

    void update(int i, int val)
    {
        int offset = val - temp[i];
        temp[i] = val;
        for (int j = i; j < this->nums.size(); j++)
        {
            nums[j] += offset;
        }
    }

    int sumRange(int i, int j)
    {
        if(i == 0)
            return nums[j];
        else
        {
            return nums[j] - nums[i - 1];
        }
        
    }
};

线段树

class NumArray
{
struct  SegNode
{
    int val;
    int addmark; //延迟更新
};
vector<SegNode> v;
int n;

public:
    NumArray(vector<int> nums)
    {
        //
        if(nums.size() <= 0)
            return;
        n = nums.size() - 1;
        v = vector<SegNode>(nums.size() * 4 + 1);
        buildTree(0, 0, n, nums);
    }
    ~NumArray()
    {
    }

    void buildTree(int root, int start, int end, vector<int> &nums)
    {
        if(start == end)
        {
            v[root].val = nums[start];
        }
        else
        {
            //*int mid = (start + end) / 2;
            int mid = start + (end - start) / 2;
            buildTree((root << 1) + 1, start, mid, nums);
            buildTree((root << 1) + 2, mid + 1, end, nums);
            v[root].val = v[(root << 1) + 1].val + v[(root << 1) + 2].val;
        }
    }

    void updateTree(int root, int start, int end, int index, int newVal)
    {
        if(start >= end)
        {
            if(index == start)
            {
                v[root].val = newVal;
            }
            return;
        }
        int mid = start + (end - start) / 2;
        if(index <= mid)
            updateTree((root << 1) + 1, start, mid, index, newVal);
        else
            updateTree((root << 1) + 2, mid + 1, end, index, newVal);
        v[root].val = v[(root << 1) + 1].val + v[(root << 1) + 2].val;
    }

    int queryTree(int root, int start, int end, int qstart, int qend)
    {
        if(start > qend || end < qstart)
        {
            return 0;
        }
        if(start >= qstart && end <= qend)
        {
            return v[root].val;
        }
        int mid = start + (end - start) / 2;
        if(qstart >= mid + 1)
        {
            return queryTree((root << 1) + 2, mid + 1, end, qstart, qend);
        }
        else if(qend <= mid)
        {
            return queryTree((root << 1) + 1, start, mid, qstart, qend);
        }
        else
        {
            int ans1 = queryTree((root << 1) + 1, start, mid, qstart, qend);
            int ans2 = queryTree((root << 1) + 2, mid + 1, end, qstart, qend);
            return ans1 + ans2;
        }
    }

    void update(int i, int val)
    {
        updateTree(0, 0, n, i, val);
    }

    int sumRange(int i, int j)
    {
        return queryTree(0, 0, n, i, j);
    }
};

树状数组

class NumArray
{
  public:
    vector<int> nums;
    vector<int> sums;
    NumArray(vector<int> nums)
    {
        this->nums = nums;
        sums.resize(nums.size() + 1);
        sums[0] = 0;
        for (int i = 0; i < nums.size(); i++)
        {
            change(i + 1, nums[i]);
        }
        /*for(auto a : sums)
        {
            cout << a << endl;
        }*/
    }

    int lowbit(int x)
    {
        return x & (-x);
    }

    int sum(int n)
    {
        int val = 0;
        while(n > 0)
        {
            val += sums[n];
            n -= lowbit(n);
        }
        return val;
    }

    void change(int i, int val)
    {
        while(i < sums.size())
        {
            sums[i] += val;
            i += lowbit(i);
        }
    }

    void update(int i, int val)
    {
        int offset = val - nums[i];
        nums[i] = val;
        change(i + 1, offset);
    }

    int sumRange(int i, int j)
    {
        return sum(j + 1) - sum(i);
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值