package com.interview.misc; import java.util.HashMap; import java.util.Map; import java.util.NavigableMap; import java.util.TreeMap; /** * Date 03/03/2016 * @author Tushar Roy * * Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. * * Time complexity O(nlogn) * Space complexity O(n) * * Performance can be improved by using self balancing BST which keeps the count of key and size of substree under it * * https://leetcode.com/problems/count-of-range-sum/ */ public class CountRanges { public int countRangeSum(int[] nums, int lower, int upper) { TreeMap<Long, Integer> map = new TreeMap<>(); Map<Long, Integer> countMap = new HashMap<>(); long prefixSum[] = new long[nums.length + 1]; map.put(0l, 1); countMap.put(0l, 1); int count = 0; for (int i = 0; i < nums.length; i++) { prefixSum[i+1] = prefixSum[i] + nums[i]; NavigableMap<Long, Integer> rangeMap = map.subMap(prefixSum[i+1] - upper, true, prefixSum[i+1] - lower, true); if (rangeMap.size() > 0) { for (int c : rangeMap.values()) { count += c; } } if (countMap.containsKey(prefixSum[i+1])) { countMap.put(prefixSum[i+1], countMap.get(prefixSum[i+1]) + 1); } else { countMap.put(prefixSum[i+1], 1); } map.put(prefixSum[i+1], countMap.get(prefixSum[i+1])); } return count; } public static void main(String args[]) { CountRanges cr = new CountRanges(); int[] input = {0, 0}; System.out.print(cr.countRangeSum(input, 0, 0)); } }