Given an array of integers find the number of all ordered pairs of elements in the array whose sum lies in a given range [a,b]
Here is an O(n^2) solution for the same <
Sort the array first and count the pairs by two indexes. The two indexes approach is similar to the one in 2-sum problem, which avoids the binary-search for N
times. The time consuming of the algorithm is Sort Complexity + O(N)
, typically, sort is O(NlnN), thus this approach is O(NlnN). The idea of the algorithm is, for an index i
, find an lower bound and an upper bound such that a <= arr[i]+arr[low] <= arr[i]+arr[high] <= b
and when i
increases, what we should do is to decrease low
and high
to hold the condition. To avoid counting the same pair twice, we keep low > i
, also we keep low <= high
. The complexity of the following counting approach is O(N), because, in the while loop
, what we can do is ++i
or --low
or --high
and there are at most N
such operations.
//count pair whose sum is in [a, b]
//arr is a sorted array with size integers.
int countPair(int arr[], int size, int a, int b) {
int cnt = 0;
int i = 0, low = size-1, high = size-1;
while (i < high) {
//find the lower bound such that arr[i] + arr[low] < a,
//meanwhile arr[i]+arr[low+1] >= a
low = max(i, low);
while (low > i && arr[i] + arr[low] >= a) --low;
//find an upper bound such that arr[i] + arr[high] <= b
//meanwhile, arr[i]+arr[high+1] > b
while (high > low && arr[i] + arr[high] > b) --high;
//all pairs: arr[i]+arr[low+1], arr[i]+arr[low+2],...,arr[i]+arr[high]
//are in the rage[a, b], and we count it as follows.
cnt += (high-low);
++i;
}
return cnt;
}