"Regional and retrieve 307. - modifiable array" - segment tree

leetcode  307. Regional and retrieve - array can be modified

Given an array of integers nums, the array element from the sum of the index i to j within the range of elements (i ≤ j), comprising i, j points.

update (i, val) function can be updated by the value of the subscript i is val, thus the number of columns to be modified.

Example:

Given nums = [1, 3, 5]

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

 

Source: stay button (LeetCode)
link: https: //leetcode-cn.com/problems/range-sum-query-mutable
copyrighted by deduction from all networks. Commercial reprint please contact the authorized official, non-commercial reprint please indicate the source.

 

Tree line on Baidu Encyclopedia definition:

Segment tree is a binary search tree , and the interval tree is similar, it means a section partitioned into intervals, a leaf node corresponding to each unit section of the segment tree.
For each non-segment tree leaf node [a, b], the interval its left son represented by [a, (a + b) / 2], segment the right son represented by [(a + b) / 2 + 1, b]. Therefore segment tree is a balanced binary tree , the last number of child nodes is N, i.e., the entire length of the line section.
Using the segment tree can quickly find a particular node number appearing in a number of line segments, the time complexity of O (logN). Without the optimization of space complexity is 2N, so sometimes need to make discrete space compression.
 
 
Since the subject of a considerable number of operations on the array to be modified:
(1) If the original data structure directly, i.e., modify the array, each modification will take O (1), each time interval and outputs will take O (n) time complexity
(2) But when we set up an interval and the tree line, and the output of each modification will take O (logn) time complexity
 
A binary tree structure to organize segment tree:
class NumArray {
    TreeNode* root;
    vector<int> num;
    int n;
public:

    NumArray(vector<int>& nums) {
        n=nums.size()-1;
        num=nums;
        if(n>=0)
            root=creatTree(nums,0,n); //针对初始化时数组为[[]]
    }

    TreeNode* creatTree(vector<int>& nums,int x, int y )
    {
        if(x==y)
        {
            TreeNode* tmp=new TreeNode(nums[x]);
            return tmp;
        }
        else
        {
            int sum=0;
            for(int i=x;i<=y;i++)
            {
                sum+=nums[i];
            }
            TreeNode* tmp = new TreeNode(sum);
            int mid=(x+y)/2;
            tmp->left=creatTree(nums,x,mid);
            tmp->right=creatTree(nums,mid+1,y);
            return tmp;
        }
    }
    
    void update(int i, int val) {
        TreeNode* r=root;
        int leftBorder=0,rightBorder=n;
        while(r)
        {
            r->val=r->val-num[i]+val;
            int mid = (leftBorder+rightBorder)/2;
            if(i<=mid)
            {
                r=r->left;
                rightBorder=mid;
            }
            else
            {
                r=r->right;
                leftBorder=mid+1;
            }
        }
        num[i]=val;
    }
    int sum(TreeNode* r, int i, int j, int leftBorder, int rightBorder)
    {
        if(r==NULL)return 0;
        if(i==leftBorder&&j==rightBorder)return r->val;
        int mid = (leftBorder+rightBorder)/2;
        if(i<=mid&&j>mid)
        {
            return sum(r->left, i, mid, leftBorder, mid)+sum(r->right, mid+1, j, mid+1, rightBorder);
        }
        else if(i<=mid)
        {
            return sum(r->left, i, j, leftBorder, mid);
        }
        else if(i>mid)
        {
            return sum(r->right, i, j, mid+1, rightBorder);
        }
        return INT_MAX;
    }
    int sumRange(int i, int j) {
        TreeNode* r=root;
        return sum(r, i ,j, 0, n);
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray* obj = new NumArray(nums);
 * obj->update(i,val);
 * int param_2 = obj->sumRange(i,j);
 */

 

Fenwick tree with organized segment tree:

class NumArray {
    vector<int> segmTree;;
    int n;
public:
    NumArray(vector<int>& nums) {
        n=nums.size()-1;
        if(n >= 0)
            buildSegmTree(nums,0,0,n);
    }
   //自底向上建树
    void buildSegmTree(vector<int>& nums,int cur, int begin, int end )
    {
        while(cur >= segmTree.size())segmTree.push_back(0);
        if(begin == end)
        {
            segmTree[cur] = nums[begin];
        }
        else
        {
            int mid = (begin + end) / 2;
            int left = cur * 2 + 1;    //左子区间下标
            int right = cur * 2 + 2;    //右子区间下标
            buildSegmTree(nums,left,begin,mid);
            buildSegmTree(nums,right,mid+1,end);
            segmTree[cur] = segmTree[left] + segmTree[right];
        }
    }
  //自底向上更新
void updateSegmTree(int cur, int begin, int end, int i, int val) { if(begin > end)return; if(begin == end) { segmTree[cur]=val; return; } int mid = (begin + end) / 2; int left = 2 * cur + 1; int right = 2 * cur +2; if(i <= mid && i >= begin) { updateSegmTree(left, begin, mid, i, val); } else { updateSegmTree(right, mid+1, end, i, val); } segmTree[cur] = segmTree[left] + segmTree[right]; } void update(int i, int val) { updateSegmTree(0, 0, n, i, val); }
  //自顶向下找区间
int sum( int cur, int i, int j, int begin, int end) { if(i > end || j < begin)return 0; if(i <= begin && j >= end) return segmTree[cur]; int mid = (begin + end) / 2; int left = cur*2 + 1; int right = cur*2 + 2; return sum(left, i, j, begin, mid)+sum(right, i, j, mid+1, end); } int sumRange(int i, int j) { return sum(0, i ,j, 0, n); } };

 

Guess you like

Origin www.cnblogs.com/Dancing-Fairy/p/12605309.html