0

The problem statement asks the number of such subarrays where i < j < k, such that sum of any two numbers should be greater than or equal to the third in the subarray:

What I did:

I ran a loop from i=0 till n-2: and the basic logic I used was if the first two elements in the sorted subarray are greater than or equal to the maximum, then all pairs will be greater than any element. and every time I get the subarray, I add the next element into it and set those three variables again. Am passing 15/20 TCs other am getting TLE:
Constraints:
1<=n<=10^5
1<=ai<=10^9

for(int i=0;i<n-2;i++)
{
    int r=i+2;
    vector<int> temp(inp.begin()+i,inp.begin()+r+1);
    sort(temp.begin(),temp.end());
    max_elem=temp[1];min_elem=temp[0];
    int maximum=temp[temp.size()-1];


    //cout<<max_elem<<" "<<min_elem<<"\n";

    while(r<n && max_elem+min_elem >= maximum)
    {   
        //cout<<max_elem<<" "<<min_elem<<" "<<inp[r]<<"\n";
        cnt++;
        r++;

        if(inp[r]<min_elem) {max_elem=min_elem;min_elem=inp[r];}
        else if(inp[r]<max_elem) max_elem=inp[r];
        else if(inp[r]>maximum) maximum=inp[r];

    }

}
cout<<cnt<<"\n";

Sample TC:

I1:
5
7 6 5 3 4
O1:
6
Explanation:
6 subarrays fulfill the conditions: (7,6,5),(7,6,5,3),(7,6,5,3,4),(6,5,3),(6,5,3,4),(5,3,4).

I2:
5
1 2 3 5 6
O2:
3
Explanation:
(1,2,3),(2,3,5),(3,5,6) --(NOTE: 1,2,3,5 isn't the ans coz 1+2 < 5 )

Behl
  • 129
  • 10

2 Answers2

0

A naive approach to do this is this is as the following. Your logic is correct and it is what I implemented. I changed the sort (NlogN) with a single pass (N) finding only the 2 smallest and largest numbers. I haven't compiled the code and not sure it works as intended. It has the overall complexity of (N*N*N).

Execution time can be improved by doing some extra checks:

  • min1 + min2 >= maxcondition can be checked after each inner (k) loop, breaking if it violates for single case.
  • If condition is not satisfied for say subarray 4-7, there is no need to check any other substring including 4-7. By storing violating cases and checking against them before each loop, overall execution time can be improved.

    int min1;
    int min2;
    int max;
    int count = 0;
    for(int i = 2; i < n; i++){
        for(int j = 0; j < i - 2; j++){
            max = -1;
            min1 = min2 = 1000000000;
            for(int k = j; k <= i; k++){
                if(inp[k] > max)
                    max = inp[k];
                if(inp[k] < min1){
                    min1 = inp[k];
                    continue;
                }
                if(inp[k] < min2){
                    min2 = inp[k];
                }
            }
            if(min1 + min2 >= max)
                count++;
        }
    } 
    
Emut
  • 319
  • 4
  • 10
0

There might be some bugs, but here is the general idea for a O(n log n) solution:

We keep a windows of elements from startIdx to endIdx. If its a valid subarray, it means we can expand it, we can add another element to it, so we increase endIdx. If its not valid, it wouldnt be valid no matter how much we expand it, so we need to reduce it by increasing startIdx.

pseudocode:

multiset<int> nums;

int startIdx = 0, endIdx = 0;
int sol = 0;

while(endIdx != inp.size()) {
    if (endIdx - startIdx < 3) {
       nums.add(inp[endIdx]);  
       endIdx++;
    } else  {
       if (nums.lowestElement() + nums.secondLowestElement() < nums.highestElement()) {
          nums.remove(nums.find(inp[startIdx]));
          startIdx++;
       } else { 
            sol += endIdx - startIdx - 2; // amount of valid subarrays ending in inp[endIdx - 1]
            nums.add(inp[endIdx]);  
            endIdx++;
       }
    }
}
juvian
  • 15,875
  • 2
  • 37
  • 38
  • But that's what I did, It's still giving TLE. – Behl Jun 18 '18 at 18:54
  • @Behl not exactly the same. Consider that all elements are 1, so every subarray of at least 3 elements is valid. Then with 10^5 elements, there are 1 + 2 + 3 + 4... + n - 2 solutions, which is in the order of 10^10. Your code would count each of these (cnt++), giving TLE. Mine will count a lof of these together, my sol += part only runs 10^5 times – juvian Jun 18 '18 at 19:00