Interval Sum

Given an integer array (index from 0 to n-1, where n is the size of this array), and an query list. Each query has two integers [start, end]. For each query, calculate the sum number between index start and end in the given array, return the result list.

Example

Example 1:

Input: array = [1,2,7,8,5],  queries = [(0,4),(1,2),(2,4)]
Output: [23,9,20]

Example 2:

Input: array : [4,3,1,2],  queries : [(1,2),(0,2)]
Output: [4,8]

Challenge

O(logN) time for each query

Notice

We suggest you finish problem Segment Tree BuildSegment Tree Query and Segment Tree Modify first.

思路:因为这个题目不需要modify数组操作,所以用prefix sum array就可以解决,O(N + M) N是数组大小,M是query次数;

注意:prefixsum一般都是用PrefixSum[n+1]的数组,prefix[0] = 0; 那么

因为i, j 是A里面的坐标,而prefixsum比A多了1;所以原来的sum[j] - sum[i-1]变成了

sum(i~j) = prefixsum(j + 1) - prefixsum(i);

/**
 * Definition of Interval:
 * public classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this.start = start;
 *         this.end = end;
 *     }
 * }
 */

public class Solution {
    /**
     * @param A: An integer list
     * @param queries: An query list
     * @return: The result list
     */
    public List<Long> intervalSum(int[] A, List<Interval> queries) {
        List<Long> list = new ArrayList<>();
        int n = A.length;
        long[] prefixsum = new long[n + 1];
        prefixsum[0] = 0;
        for(int i = 1; i <= n; i++) {
            prefixsum[i] = prefixsum[i - 1] + A[i - 1];
        }
        
        for(Interval interval: queries) {
            list.add(prefixsum[interval.end + 1] - prefixsum[interval.start]);
        }
        return list;
    }
}

思路2:其实,这个题目是为了后面的follow up做准备的,LogN time for query;

如果数组是个动态的, 那么就要用到segment tree或者树状数组;

现在这里用segment tree来做解答;Time: m Log(K) , m是query的次数,K是数组里面的最大值;Space: O(N) 

/**
 * Definition of Interval:
 * public classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this.start = start;
 *         this.end = end;
 *     }
 * }
 */

public class Solution {
    /**
     * @param A: An integer list
     * @param queries: An query list
     * @return: The result list
     */
    public List<Long> intervalSum(int[] A, List<Interval> queries) {
        List<Long> list = new ArrayList<>();
        SegmentTree segmentTree = new SegmentTree(A);
        for(Interval interval: queries) {
            list.add(segmentTree.query(interval.start, interval.end));
        }
        return list;
    }
    
    private class SegmentTreeNode {
        public int start, end;
        public long sum;
        public SegmentTreeNode left, right;
        public SegmentTreeNode (int start, int end) {
            this.start = start;
            this.end = end;
            this.sum = 0;
            this.left = null;
            this.right = null;
        }
    }
    
    private class SegmentTree {
        public SegmentTreeNode root;
        public int size;
        
        public SegmentTree(int[] A) {
            this.size = A.length;
            this.root = buildTree(A, 0, size - 1);
        }
        
        private SegmentTreeNode buildTree(int[] A, int start, int end) {
            if(start > end) {
                return null;
            }
            SegmentTreeNode node = new SegmentTreeNode(start, end);
            if(start == end) {
                node.sum = A[start];
                return node;
            }
            int mid = start + (end - start) / 2;
            node.left = buildTree(A, start, mid);
            node.right = buildTree(A, mid + 1, end);
            node.sum = node.left.sum + node.right.sum;
            return node;
        }
        
        private long querySum(SegmentTreeNode root, int start, int end) {
            if(root.start == start && root.end == end) {
                return root.sum;
            }
            int mid = root.start + (root.end - root.start) / 2;
            long leftsum = 0, rightsum = 0;
            if(start <= mid) {
                leftsum = querySum(root.left, start, Math.min(mid, end));
            }
            if(end >= mid + 1) {
                rightsum = querySum(root.right, Math.max(start, mid + 1), end);
            }
            return leftsum + rightsum;
        }
        
        public long query(int start, int end) {
            return querySum(root, start, end);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值