-1

I am solving a problem.

    Count of Range Sum

    Given an integer array nums, return the number of range sums that 
    lie in [lower, upper] inclusive. Range sum S(i, j) is defined as 
    the sum of the elements in nums between indices i and j (i ≤ j),inclusive.
    Example: Given nums = [-2, 5, -1], lower = -2, upper = 2, Return 3.
    The three ranges are : [0, 0], [2, 2], [0, 2] and their respective sums are: -2, -1, 2

My solution is below:

1.get all sums from[0,i] as sum[i]

2.sort sum vector as clone vector, and reindex elements in sum according to its index in clone vector. Put sum element value as map reflect's key, new index as reflect's value. add vector sum element from back to front into Binary Indexed Tree, and at the same time find valid elements index range [idx1,idx2] in clone which satisfies the lowerbound and upperbound condition.

3.get the sum from node 0 to node idx1 and sum from node 0 to node idx2 in our BIT. If the node is inserted into the BIT already we will find the node in our BIT. So the node amount which satisfies our bound conditifon is the sum.

 public:
 vector<long>tree,clone;
 int countRangeSum(vector<int>& nums, int lower, int upper) {
 int n=nums.size();
 vector<long>sum(n+1);
 for(int i=1;i<=n;i++)
 sum[i]=sum[i-1]+nums[i-1];// step1

 clone=sum;
 sort(clone.begin(),clone.end());
 tree.resize(sum.size()+1);
 unordered_map<long,int>reflect;
 for(int i=0;i<clone.size();i++)
 reflect[clone[i]]=i;//step2

 int res=0;
 for(int i=sum.size()-1;i>=0;i--)
 {

   int idx1=binarysearch(sum[i]+lower,true);
   int idx2=binarysearch(sum[i]+upper,false);

   res=res+count(idx2)-count(idx1);
   add(reflect[sum[i]]); //step3
 }
 return res;
 }




 int binarysearch(long val, bool includeself)
{  
if(includeself)
return lower_bound(clone.begin(),clone.end(),val)-clone.begin();
return upper_bound(clone.begin(),clone.end(),val)-clone.begin();
}





void add(int pos){
pos=pos+1;
while(pos<tree.size())
{
    tree[pos]++;
    pos=pos+(pos&-pos);
}
}




int count(int pos){
int cnt=0;
pos=pos+1;
while(pos>0)
{
    cnt=cnt+tree[pos];
    pos=pos-(pos&-pos);
}
return cnt;
}

Errors: Input: [-2,5,-1] -2 2 Output: 197 Expected: 3

And I don't really know how to format my code, I always wrote c++ like this so..

Sorry it gets a bit long, I thought it for several days still no clue where goes wrong. Any thought is appreciated!!

Isabella Lu
  • 1
  • 2
  • 3
  • 1
    Please help us to help you. What is wrong with the code? Do you get a compiler error? Runtime error? Wrong result? In any case you should post a [MCVE] and please format the code properly, at the moment it is rather difficult to read – 463035818_is_not_an_ai Jul 20 '16 at 22:23
  • 1
    I highly recommend a tool, maybe you've heard of it, called a **Debugger**. Very useful for finding issues in code. – Thomas Matthews Jul 20 '16 at 22:29

1 Answers1

0

It was hard for me to understand how you are trying to use the Binary Indexed Tree, but I think I get it.

Let me try to explain what I think the algorithm is, using n as the length of the input array.

  1. Compute all of the range sums for which the range begins with index 0.
  2. Sort these sums in increasing order.
  3. Initialize a Binary Indexed Tree of size n that represents a frequency count of 0 at each position. This represents that all of the sums you start with are invalid, and it will be used to keep track of which sums become valid as the algorithm progresses.
  4. Implicitly offset all of the sums by the range sum S(0, n) so that you obtain range sums for which the range begins with index n rather than index 0.
  5. Determine the indices within the list of sorted sums of the smallest and largest sum that fall into [lower bound, upper bound].
  6. Query the Binary Indexed Tree to count how many of these sums are valid. Add this to your count of the total number of range sums that fall into [lower bound, upper bound]
  7. Identify the index of the range sum S(0,n) in the Binary Indexed Tree and mark that it will be a valid sum in the next iteration by setting its frequency count to 1.
  8. Loop back to step 4, iterating through n - 1, n - 2, n - 3, . . ., 2, 1, 0.

The most significant problem with your implementation, I think, is that your tree is not quite large enough. It should be a little larger because the 0 index is not used. So use

tree.resize(sum.size()+2);

instead of your current +1.

Also, if you want to be able to use the method more than once, you will need to clear out the tree, setting all values back to zero, rather than just resizing it.

Fixing the first problem made it work on your sample data. I didn't notice any other problems with your code, but I didn't test thoroughly.

Evan VanderZee
  • 797
  • 6
  • 10