Open In App

Count of pairs such that A[i], i, A[j] and j are in increasing order

Last Updated : 01 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A[] of N integers, the task is to find the number of pairs of indices (1 ? i, j ? N) in the array such that A[i] < i < A[j] < j.

Examples:

Input: N = 8, A[] = {1, 1, 2, 3, 8, 2, 1, 4}
Output: 3
Explanation: The pairs satisfying the given condition are {(2, 4), (2, 8), (3, 8)}. 
For the pair (2, 4): A[2] = 1(1-based indexing), A[4] = 3 and 1 < 2 < 3 < 4.
For the pair (2, 8): A[2] = 1, A[8] = 4 and 1 < 2 < 4 < 8.
For the pair (3, 8): A[3] = 2, A[8] = 4 and 2 < 3 < 4 < 8.

Input: N = 2, A[] = {1, 2}
Output: 0

Naive Approach: A basic way to solve the problem would be to traverse the array using two nested loops and check the condition for each possible pair.

C++




// C++ program to count pairs such that A[i], i, A[j] and j are in increasing order
#include <iostream>
using namespace std;
 
int countPairs(int A[], int N)
{
 
    int count = 0;
 
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            if (A[i] < i + 1 && i + 1 < A[j] && A[j] < j + 1) {
                count++;
            }
        }
    }
 
    return count;
}
 
int main()
{
 
    int N = 8;
    int A[] = { 1, 1, 2, 3, 8, 2, 1, 4 };
 
    cout << countPairs(A, N);
 
    return 0;
 
}
  // This code is contributed by muditj148.


Java




/*package whatever //do not write package name here */
 
import java.io.*;
 
class GFG {
   
  static int countPairs(int A[], int N){
       
    int count = 0;
     
    for(int i=0;i<N;i++){
        for(int j=i+1;j<N;j++){
          if(A[i]<i+1 && i+1<A[j] && A[j]<j+1){
              count++;
          }
        }
    }
     
    return count;
  }
   
    public static void main (String[] args) {
         
           int N = 8;
         int A[] = { 1, 1, 2, 3, 8, 2, 1, 4 };
         int answer = countPairs(A, N);
 
          System.out.println(answer);
    }
}


Python3




class GFG :
    @staticmethod
    def  countPairs( A,  N) :
        count = 0
        i = 0
        while (i < N) :
            j = i + 1
            while (j < N) :
                if (A[i] < i + 1 and i + 1 < A[j] and A[j] < j + 1) :
                    count += 1
                j += 1
            i += 1
        return count
    @staticmethod
    def main( args) :
        N = 8
        A = [1, 1, 2, 3, 8, 2, 1, 4]
        answer = GFG.countPairs(A, N)
        print(answer)
     
if __name__=="__main__":
    GFG.main([])
     
    # This code is contributed by aadityaburujwale.


C#




// Include namespace system
using System;
public class GFG
{
    public static int countPairs(int[] A, int N)
    {
        var count = 0;
        for (int i = 0; i < N; i++)
        {
            for (int j = i + 1; j < N; j++)
            {
                if (A[i] < i + 1 && i + 1 < A[j] && A[j] < j + 1)
                {
                    count++;
                }
            }
        }
        return count;
    }
    public static void Main(String[] args)
    {
        var N = 8;
        int[] A = {1, 1, 2, 3, 8, 2, 1, 4};
        var answer = GFG.countPairs(A, N);
        Console.WriteLine(answer);
    }
}


Javascript




<script>
// Javascript program for above approach
function countPairs( A, N)
    {
        var count = 0;
        for (var i = 0; i < N; i++)
        {
            for (var j = i + 1; j < N; j++)
            {
                if (A[i] < i + 1 && i + 1 < A[j] && A[j] < j + 1)
                {
                    count++;
                }
            }
        }
        return count;
    }
 
// Driver Code
        var N = 8;
        var A = [1, 1, 2, 3, 8, 2, 1, 4];
        var answer = countPairs(A, N);
        document.write(answer);
 
        // This code is contributed by code_hunt.                  
</script>


Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: The problem can be solved using a greedy approach and binary search

Given Condition is A[i] < i < A[j] < j. Lets break it into three separate conditions:

  • A[i] < i
  • i < A[j]
  • A[j] < j

The elements of array having A[i] ? i will not satisfy the 1st and 3rd condition and hence will not be the part of any pair satisfying the given condition. For rest of the elements (say valid elements) 1st and 3rd conditions are already satisfied. So, among the valid elements, simply count the number of pairs (i, j) satisfying the 2nd condition i.e. i < A[j].

Follow the steps to solve the problem:

  • Initialize a variable (say ans) with 0, to store the total number of pairs and a vector (say v) to store the positions of valid elements.
  • While iterating through the array, if an element is greater than or equal to its position, then skip the iteration, as that element would never be able to form a pair satisfying the required conditions.
  • Else, just add the number of positions less than the current element to the answer (to satisfy the 2nd condition i < A[j]), which can be calculated by the lower bound on vector v of positions.
  • Also, at end of each iteration, insert the position of each valid element to the vector v.

Below is the implementation for the above approach:

C++




// C++ code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to Count number of pairs (i, j) in
// array such that A[i]<i<A[j]<j
int countPairs(int A[], int N)
{
    // Variable to store total number of pairs
    int ans = 0;
 
    // Vector to store positions of
    // valid elements
    vector<int> v;
 
    // Iterating through the array
    for (int i = 0; i < N; i++) {
 
        // If an element is greater than its
        // position in array we simply skip
        // the iteration
        if (A[i] >= (i + 1)) {
            continue;
        }
 
        // Else we add the number of positions
        // less than the current valid element
        // to the answer
        ans += lower_bound(v.begin(), v.end(), A[i]) - v.begin();
 
        // insert position of each valid
        // element in vector v
        v.push_back(i + 1);
    }
 
    // Return answer
    return ans;
}
 
// Driver Code
int main()
{
    int N = 8;
    int A[] = { 1, 1, 2, 3, 8, 2, 1, 4 };
    int answer = countPairs(A, N);
 
    // Function Call
    cout << answer << endl;
    return 0;
}


Java




// Java code for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Function to find lower_bound
  static int lower_bound(List<Integer> nums, int target)
  {
    int i = 0;
    int j = nums.size() - 1;
    while (i <= j) {
      int m = i + (j - i) / 2;
      if (nums.get(m) >= target) {
        j = m - 1;
      }
      else {
        i = m + 1;
      }
    }
    return i;
  }
 
  // Function to Count number of pairs (i, j) in
  // array such that A[i]<i<A[j]<j
  static int countPairs(int[] A, int N)
  {
    // Variable to store total number of pairs
    int ans = 0;
 
    // ArrayList to store positions of
    // valid elements
    List<Integer> v = new ArrayList<>();
 
    // Iterating through the array
    for (int i = 0; i < N; i++) {
      // If an element is greater than its
      // position in array we simply skip
      // the iteration
      if (A[i] >= (i + 1)) {
        continue;
      }
 
      // Else we add the number of positions
      // less than the current valid element
      // to the answer
      ans += lower_bound(v, A[i]);
 
      // insert position of each valid
      // element in ArrayList v
      v.add(i + 1);
    }
 
    // Return answer
    return ans;
  }
 
  public static void main(String[] args)
  {
    int N = 8;
    int[] A = { 1, 1, 2, 3, 8, 2, 1, 4 };
    int answer = countPairs(A, N);
 
    // Function call
    System.out.println(answer);
  }
}
 
// This code is contributed by lokesh.


Python3




# python3 code for the above approach
from bisect import bisect_left
 
# Function to Count number of pairs (i, j) in
# array such that A[i]<i<A[j]<j
 
 
def countPairs(A, N):
 
    # Variable to store total number of pairs
    ans = 0
 
    # Vector to store positions of
    # valid elements
    v = []
 
    # Iterating through the array
    for i in range(0, N):
 
        # If an element is greater than its
        # position in array we simply skip
        # the iteration
        if (A[i] >= (i + 1)):
            continue
 
        # Else we add the number of positions
        # less than the current valid element
        # to the answer
        ans += bisect_left(v, A[i], lo=0, hi=len(v),)
 
        # insert position of each valid
        # element in vector v
        v.append(i + 1)
 
    # Return answer
    return ans
 
 
# Driver Code
if __name__ == "__main__":
 
    N = 8
    A = [1, 1, 2, 3, 8, 2, 1, 4]
    answer = countPairs(A, N)
 
    # Function Call
    print(answer)
 
    # This code is contributed by rakeshsahni


C#




// C# code for the above approach
 
using System;
using System.Collections;
 
public class GFG {
 
    // Function to find lower_bound
    static int lower_bound(ArrayList nums, int target)
    {
        int i = 0;
        int j = nums.Count - 1;
        while (i <= j) {
            int m = i + (j - i) / 2;
            if ((int)nums[m] >= target) {
                j = m - 1;
            }
            else {
                i = m + 1;
            }
        }
        return i;
    }
 
    // Function to Count number of pairs (i, j) in
    // array such that A[i]<i<A[j]<j
    static int countPairs(int[] A, int N)
    {
        // Variable to store total number of pairs
        int ans = 0;
 
        // ArrayList to store positions of
        // valid elements
        ArrayList v = new ArrayList();
 
        // Iterating through the array
        for (int i = 0; i < N; i++) {
            // If an element is greater than its
            // position in array we simply skip
            // the iteration
            if (A[i] >= (i + 1)) {
                continue;
            }
 
            // Else we add the number of positions
            // less than the current valid element
            // to the answer
            ans += lower_bound(v, A[i]);
 
            // insert position of each valid
            // element in ArrayList v
            v.Add(i + 1);
        }
 
        // Return answer
        return ans;
    }
 
    static public void Main()
    {
 
        // Code
        int N = 8;
        int[] A = { 1, 1, 2, 3, 8, 2, 1, 4 };
        int answer = countPairs(A, N);
 
        // Function call
        Console.WriteLine(answer);
    }
}
 
// This code is contributed by lokeshmvs21.


Javascript




// Javascript code for the above approach
 
  // Function to find lower_bound
  function lower_bound(nums, target)
  {
    let i = 0;
    let j = nums.length - 1;
    while (i <= j) {
      let m = Math.round(i + (j - i) / 2);
      if (nums[m] >= target) {
        j = m - 1;
      }
      else {
        i = m + 1;
      }
    }
    return i;
  }
 
  // Function to Count number of pairs (i, j) in
  // array such that A[i]<i<A[j]<j
  function countPairs( A, N)
  {
   
    // Variable to store total number of pairs
    let ans = 0;
 
    // ArrayList to store positions of
    // valid elements
    let v= [];
 
    // Iterating through the array
    for (let i = 0; i < N; i++)
    {
     
      // If an element is greater than its
      // position in array we simply skip
      // the iteration
      if (A[i] >= (i + 1)) {
        continue;
      }
 
      // Else we add the number of positions
      // less than the current valid element
      // to the answer
      ans += lower_bound(v, A[i]);
       
      // insert position of each valid
      // element in ArrayList v
      v.push(i + 1);
    }
 
    // Return answer
    return ans;
  }
 
   
    let N = 8;
    let A = [ 1, 1, 2, 3, 8, 2, 1, 4 ];
    let answer = countPairs(A, N);
 
    // Function call
    console.log(answer);
   
  // This code is contributed by garg28harsh.


Output

3

Time Complexity: O(N * log(N))
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads