目錄
307. 區域和檢索 - 數組可修改
題目描述:
實現代碼與解析:
樹狀數組:
原理思路:
307. 區域和檢索 - 數組可修改
題目描述:
????????給你一個數組?nums
?,請你完成兩類查詢。
- 其中一類查詢要求?更新?數組?
nums
?下標對應的值 - 另一類查詢要求返回數組?
nums
?中索引?left
?和索引?right
?之間(?包含?)的nums元素的?和?,其中?left <= right
實現?NumArray
?類:
NumArray(int[] nums)
?用整數數組?nums
?初始化對象void update(int index, int val)
?將?nums[index]
?的值?更新?為?val
int sumRange(int left, int right)
?返回數組?nums
?中索引?left
?和索引?right
?之間(?包含?)的nums元素的?和?(即,nums[left] + nums[left + 1], ..., nums[right]
)
示例 1:
輸入: ["NumArray", "sumRange", "update", "sumRange"] [[[1, 3, 5]], [0, 2], [1, 2], [0, 2]] 輸出: [null, 9, null, 8]解釋: NumArray numArray = new NumArray([1, 3, 5]); numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9 numArray.update(1, 2); // nums = [1,2,5] numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
提示:
1 <= nums.length <= 3 *?104
-100 <= nums[i] <= 100
0 <= index < nums.length
-100 <= val <= 100
0 <= left <= right < nums.length
- 調用?
update
?和?sumRange
?方法次數不大于?3 * 104
?
實現代碼與解析:
樹狀數組:
class NumArray {
public:vector<int> tr = vector<int>(1000010);int lowbit(int x) {return x & -x;}int query(int x) {int res = 0;for (int i = x; i > 0; i -= lowbit(i)) res += tr[i];return res;}void add(int x, int u) {for (int i = x; i <= n; i += lowbit(i)) tr[i] += u;}vector<int> nums;int n;NumArray(vector<int>& nums) {n = nums.size();this->nums = nums;// 初始化 樹狀數組tr.resize(n + 1, 0);for (int i = 0; i < n; i++) add(i + 1, nums[i]);}void update(int index, int val) {add(index + 1, val - nums[index]);nums[index] = val;}int sumRange(int left, int right) {return query(right + 1) - query(left);}
};
原理思路:
? ? ? ? 如果沒有更新,用前綴和就行,但是此題數組會改變,如果每次都求一次前綴和一定超時,所以考慮用樹狀數組。
? ? ? ? 樹狀數組代碼十分好寫和簡單,背下來就可以,其具體原理可以自行查閱,理解起來還是挺難的。