数组的区间和

数组的区间和

输入一个无序的数组nums,然后可以在O(1)的时间复杂度给出区间iijj之间的元素和。

例如:

数组nums = [1,2,3,4,2,3,1],查询区间下标为1到3之间的元素的和,则返回sum = 2+3+4 = 9

如果排序的话,原来的下标之间的相对关系就变了,维护这个相对关系也是十分复杂的,因此排序是不能排序了。

看到O(1)时间复杂度,想到的应该是类似HashMap子类的数据结构。

数组区间和的问题可以通过记录整个数组元素的前缀和,然后通过两个前缀和相减即可得到区间和。

流程:

  • 预处理,sumMap[i]表示0到i之间的元素的和;
  • 计算i到j之间的区间和,利用sumMap[j] - sumMap[i-1]即可在O(1)的时间复杂度得到;


public class IntervalSum {

    private long[] sumMap = null;

    public IntervalSum(int[] num) {
        // TODO Auto-generated constructor stub
        this.sumMap = new long[num.length];
        sumMap[0] = num[0];
        for (int i = 1;i < num.length; i++) {
            sumMap[i] = num[i] + sumMap[i-1];
        }
        System.out.println(Arrays.toString(sumMap));
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] num = new int[]{1,2,3,4,5,6,7,8,9};
        IntervalSum demo = new IntervalSum(num);
        System.out.println(demo.querySum(0, 7));
    }

    public long querySum(int i, int j) {
        if (i > j || i < 0 || j >= sumMap.length) return Long.MIN_VALUE;
        return sumMap[j] - (i == 0 ? 0 : sumMap[i-1]);
    }

}

扩展:

如果某个元素的值被修改,那么sumMap也相应的需要被修改,但是修改时间复杂度为O(n),那么能不能在O(logn)的时间复杂度达到更新sumMap的目的呢?答案是:线段树,线段树常常用来解决单点更新,区间查询的问题。

关于线段树的内容,后面继续学习总结。


关于线段树的总结:https://blog.csdn.net/u014532901/article/details/79937786

原文地址:https://www.cnblogs.com/Spground/p/9567876.html