Provided that the integers are all non-negative, you could use this algorithm (pseudo-code):
countInRange(a, l, m): sumL = 0 count = 0 idxM = 0 i = 1 idxLast = len(a) for idxL = 1 to idxLast: sumL = sumL + a[idxL] while i <= idxLast and sumL >= l: if idxM <= idxL: idxM = idxL sumM = sumL while idxM <= idxLast and sumM <= m: idxM = idxM + 1 if idxM > idxLast: break sumM = sumM + a[idxM] count = count + idxM - idxL sumL = sumL - a[i] sumM = sumM - a[i] i = i + 1 return count
This algorithm runs with O(n) time complexity:
In total, the inner-most loop will never iterate more than n times. This is because the value of idxM at entering the loop:
- is never lower than 1
- is never higher than n
- is always at least one greater than the previous time the loop was entered.
In total the middle loop will never execute more than n times either, as it increments i to n, and the same is clearly true for the outer loop.