Leetcode: Range Sum Query - Mutable
来源:互联网 发布:淘宝上签证怎么办理 编辑:程序博客网 时间:2024/05/01 23:43
Given an integer array nums, find the sum of the elements between indicesi andj (i ≤ j), inclusive.
The update(i, val) function modifies nums by updating the element at indexi toval.Example:
Given nums = [1, 3, 5]sumRange(0, 2) -> 9update(1, 2)sumRange(0, 2) -> 8
Note:
- The array is only modifiable by the update function.
- You may assume the number of calls to update and sumRange function is distributed evenly
比较困难,主要是需要小于O(N)的时间复杂度。新的知识点,可以用树状数组(Binary Indexed Tree)或者线段树(Segment tree)来解决。
Binary Indexed Tree的特点 (from baidu): 每个节点x管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。求二进制最右边的1代表的数值可以用 (x & -x)。这样更新和求和都是log(N)的时间复杂度。
class NumArray {public: NumArray(vector<int> &nums) { m_bitSums.resize(nums.size() + 1); m_origNums.resize(nums.size() + 1); for (int i = 0; i < nums.size(); ++i) { update(i, nums[i]); } } void update(int i, int val) { int delta = val - m_origNums[++i]; m_origNums[i] = val; while (i < m_bitSums.size()) { m_bitSums[i] += delta; i += (i & -i); } } int sumRange(int i, int j) { return (i == j) ? m_origNums[i+1] : getSum(j+1) - getSum(i); } private: int getSum(int i) { int result = 0; while (i > 0) { result += m_bitSums[i]; i -= (i & -i); } return result; }private: vector<int> m_bitSums; vector<int> m_origNums;};// Your NumArray object will be instantiated and called as such:// NumArray numArray(nums);// numArray.sumRange(0, 1);// numArray.update(1, 10);// numArray.sumRange(1, 2);
From baidu - Segment tree是一种二叉搜索树,具有平衡的特点。它将一个区间分割成单元区间,对应叶节点。线段树是建立在线段的基础上,每个结点都代表了一条线段[a,b]。长度为1的线段称为元线段。非元线段都有两个子结点,左结点代表的线段为[a,(a + b) / 2],右结点代表的线段为[((a + b) / 2)+1,b]。
struct SegmentNode { int start; int end; int sum; SegmentNode* left; SegmentNode* right; SegmentNode(int s, int e) : start(s), end(e), sum(0), left(nullptr), right(nullptr) { }};class NumArray {public: NumArray(vector<int> &nums) { root = buildTree(nums, 0, nums.size() - 1); } void update(int i, int val) { updateTree(root, i, val); } int sumRange(int i, int j) { return sumTree(root, i, j); } private: SegmentNode* buildTree(const vector<int>& nums, int start, int end) { if (start > end) { return nullptr; } SegmentNode* node = new SegmentNode(start, end); if (start == end) { node->sum = nums[start]; } else { int mid = start + (end - start) / 2; node->left = buildTree(nums, start, mid); node->right = buildTree(nums, mid + 1, end); node->sum = node->left->sum + node->right->sum; } return node; } int updateTree(SegmentNode* root, int i, int val) { if (root == nullptr || i < root->start || i > root->end) { return 0; } if (root->start == i && root->end == i) { int diff = val - root->sum; root->sum = val; return diff; } int mid = root->start + (root->end - root->start) / 2; int diff = (i <= mid ? updateTree(root->left, i, val) : updateTree(root->right, i, val)); root->sum += diff; return diff; } int sumTree(SegmentNode* root, int i, int j) { if (root == nullptr || i > root->end || j < root->start) { return 0; } if (i <= root->start && j >= root->end) { return root->sum; } int mid = root->start + (root->end - root->start) / 2; if (i > mid) { return sumTree(root->right, i, j); } else if (j <= mid) { return sumTree(root->left, i, j); } else { return sumTree(root->left, i, mid) + sumTree(root->right, mid + 1, j); } }private: SegmentNode* root;};// Your NumArray object will be instantiated and called as such:// NumArray numArray(nums);// numArray.sumRange(0, 1);// numArray.update(1, 10);// numArray.sumRange(1, 2);
BIT效率高一些,但个人感觉Segment Tree写起来简单一些,不熟悉BIT算法。
0 0
- [LeetCode]Range Sum Query - Mutable
- Range Sum Query - Mutable -leetcode
- leetcode Range Sum Query - Mutable
- Leetcode: Range Sum Query - Mutable
- Leetcode: Range Sum Query - Mutable
- leetcode, Range Sum Query - Mutable
- LeetCode Range Sum Query - Mutable
- leetcode - Range Sum Query - Mutable
- Range Sum Query - Mutable -- Leetcode
- leetcode Range Sum Query-Mutable
- 【Leetcode】Range Sum Query - Mutable
- leetcode之Range Sum Query - Mutable
- LeetCode 题解(289): Range Sum Query - Mutable
- [leetcode-307]Range Sum Query - Mutable(java)
- leetcode 307 : Range Sum Query - Mutable
- [LeetCode 307] Range Sum Query - Mutable
- LeetCode(307) Range Sum Query - Mutable
- leetcode笔记:Range Sum Query - Mutable
- NAO机器人之开发环境搭建
- 用视图控件 实现简单的跑马灯
- 如何创建html文件
- C/C++编译和链接过程详解 (重定向表,导出符号表,未解决符号表)
- 数据结构与算法——字典序最小问题(用string类实现)
- Leetcode: Range Sum Query - Mutable
- Servlet3.0学习总结(一)——使用注解标注Servlet-2
- 信道编码——线性分组码
- EasyDarwin EasyClient开源流媒体播放器,支持多窗口显示
- 关于IO流制作简单的复制张贴功能
- Android菜单的使用
- 玩转四旋翼无人机(DJI SDK 使用)
- KJFrameForAndroid
- Eclipse的快捷键