数据结构--SQRT分解

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;
    }
}

你可能感兴趣的:(数据结构--SQRT分解)