Triplet whose sum in range (1,2)
The trick is to figure out a way to categorize the possible solutions and come up with a linear-time constant-space solution for each.
Consider the three ranges X = (0,2/3), Y = [2/3,1], Z = (1,2)
. At most one value can come from Z
(if two values came from Z
, then the sum would exceed 1+1=2
). Similarly, at least one value must come from X
. Suppose there were 3 values a <= b <= c
so that 1 <= a+b+c <= 2
. Then, consider what possible classes of solutions are feasible:
A) `a \in X, b \in X, C \in X`
B) `a \in X, b \in X, C \in Y`
C) `a \in X, b \in X, C \in Z`
D) `a \in X, b \in Y, C \in Y`
E) `a \in X, b \in Y, C \in Z`
So how can we test each case?
Case A is incredibly easy to test: the sum is guaranteed to be below 2, so we just need to test the largest sum (largest 3 elements in X) exceeds 1.
Case C is incredibly easy to test: since the sum is guaranteed to be above 1, we only need to check if the sum is below 2. So in order to do that, we just need to test the smallest 2 values in X and the smallest value in Z
Cases D and E are similar to C (since the sum must be at least 4/3 > 1, choose the smallest possible values in each class).
Case B is the only tricky case. 0 < a+b < 4/3
and 2/3 <= c <= 1
. To handle case B, we consider these intervals : X1 = (0, 1/2), X2 = [1/2 2/3), Y = [2/3, 1].
This results in following three valid cases :
B1. a in X1, b in X2, c in Y
B2. a in X1, b in X1, c in Y
B3. a in X2, b in X2, c in Y
Case B1 & B3 : Sum of three numbers is always greater than 1 so we take minimum values and check if it is smaller than 2 or not.
Case B2 : Sum of three numbers is always less than 2, so we take maximum sum and check if is greater than 1 or not.
So to summarize, the tests are:
|X| >= 3
andXmax(1) + Xmax(2) + Xmax(3) >= 1
|X| >= 2
,|Z| >= 1
, andXmin(1)+Xmin(2)+Zmin(1) <= 2
|X| >= 1
,|Y| >= 2
, andXmin(1)+Ymin(1)+Ymin(2) <= 2
|X| >= 1
,|Y| >= 1
,|Z| >= 1
, andXmin(1)+Ymin(1)+Zmin(1) <= 2
|X| >= 2
,|Y| >= 1
, andXmax(1) + Xmax(2) + Ymin(1) < 2
|X| >= 2
,|Y| >= 1
, andXmin(1) + Xmin(2) + Ymax(1) > 1
)
Each test can be performed in linear time and constant space (you only need to find Xmax(1), Xmax(2), Xmax(3), Xmin(1), Xmin(2), Ymin(1), Ymin(2), Ymax(1), Zmin(1)
, all of which can be found in one pass even if the data is not sorted)
So, you have an array of double data types of length n. Intialize three variables a,b and c as first 3 values of array.Now,iterate from i = 3 to n and check the following: 1)Check if sum falls in (1, 2),if it does then return true. 2)If not, then check if sum is greater than 2,if so, then replace MAX(a,b,c) to current element arr[i]. 3)Otherwise sum must be less than 1 then replace MIN(a,b,c) to current element arr[i].And finally after coming out of loop check once again for last triplet if sum falls in (1,2) then return true,otherwise return false.
enter code here
double a=arr[0], b=arr[1], c=arr[2];
for(int i=3 ; i<n ; i++){
// check if sum fall in (1, 2)
if(a+b+c > 1 && a+b+c < 2){
return 1;
}
// if not, then check is sum greater than 2
// if so, then replece MAX(a,b,c) to new number
else if(a+b+c > 2){
if(a>b && a>c){
a = arr[i];
}
else if(b>a && b>c){
b = arr[i];
}
else if(c>a && c>b){
c = arr[i];
}
}
// else then sum must be less than 1
// then replace MIN(a,b,c) to new number
else{
if(a<b && a<c){
a = arr[i];
}
else if(b<a && b<c){
b = arr[i];
}
else if(c<a && c<b){
c = arr[i];
}
}
}
// check for last a, b, c triplet
if(a+b+c > 1 && a+b+c < 2){
return 1;
}
else{
return 0;
}
This problem can easily be solved in linear runtime time using the sliding window sum approach. In this case, we will use a window of size 3. This is also called the 'moving sum algorithm'.
Algorithm Below
1> Prepare the window of size 3 with the first 3 elements
2> IF (array.len <= 3): CHECK IF window-sum is in the range (1,2), then RETURN accordingly
3> FOR i = 3 UPTO (array.len-1)
3.1> SORT the window (3log3 = constant time operation)
3.2> IF window-sum is in the range (1,2): RETURN 1 or TRUE
3.3> ELSE IF window-sum < 1: Replace the smallest element in the window (window[0]) with array[i]
3.4> ELSE IF window-sum > 2: Replace the largest element in the window (window[2]) with array[i]
4> Outside the loop, check the FINAL window sum and RETURN accordingly.
Access the Python code here. Star the repository, please!