SQRT分解
- 是一种数据结构
- 使用分块(分组)的思想
- 解决区间问题
- 动态维护
代码示例
leetcode 307 可变数组
给你一个数组 nums ,请你完成两类查询,其中一类查询要求更新数组下标对应的值,另一类查询要求返回数组中某个范围内元素的总和。
实现 NumArray 类:
NumArray(int[] nums) 用整数数组 nums 初始化对象
void update(int index, int val) 将 nums[index] 的值更新为 val
int sumRange(int left, int right) 返回子数组 nums[left, right] 的总和(即,nums[left] + nums[left + 1], ..., nums[right])
class NumArrayMuSqrt {
private int[] data, blocks;//block 表示每组的数据
private int N; //元素总数
private int B; //每组元素个数
private int Bn; //组数
public NumArrayMuSqrt(int[] nums) {
N = nums.length;
if (N == 0)
return;
B = (int) Math.sqrt(N);
//是否能整除
Bn = N / B + (N % B > 0 ? 1 : 0);
data = Arrays.copyOf(nums, N);
blocks = new int[Bn];
for (int i = 0; i < N; i++)
blocks[i / B] += nums[i];
}
public void update(int index, int val) {
if(index < 0 || index >= N)
return;
int b = index / B;
blocks[b] -= data[index];
blocks[b] += val;
data[index] = val;
}
public int sumRange(int x, int y) {
if (x < 0 || x >= N || y < 0 || y >= N || x > y)
return 0;
int bstart = x / B;
int bend = y / B;
int res = 0;
if (bstart == bend){
for (int i = x; i <= y; i++)
res += data[i];
return res;
}
//(bstart + 1)*B bstart组的下一组的第一个节点 从bstart 遍历到这一组的最后一个元素
for (int i = x; i < (bstart + 1) * B; i++)
res += data[i];
for (int b = bstart + 1; b < bend; b++)
res += blocks[b];
for (int i = bend * B; i <= y; i++) {
res += data[i];
}
return res;
}
}