Count of unique pairs (arr[i], arr[j]) such that i < j in C++


We are given an array containing integer elements. The goal is to find unique pairs of elements of array such that pairs of type (arr[i],arr[j]) have indexes such that i

Let us understand with examples

Input − arr[] = {1,2,3};

Output − Count of unique pairs (arr[i], arr[j]) such that i < j are − 3

Explanation − As all elements are unique. Pairs would be −

(1,2) - ( arr[0],arr[1] ) 0<1
(1,3) - ( arr[0], arr[2] ) 0<2
(2,3) - ( arr[1],arr[2] ) 1<2

Input − arr[] = { 4,4,3,2};

Output − Count of unique pairs (arr[i], arr[j]) such that i < j are − 4

Explanation − As all elements are unique. Pairs would be −

(4,4) - ( arr[0],arr[1] ) 0<1
(4,3) - ( arr[0], arr[2] ) 0<2
(4,2) - ( arr[0],arr[3] ) 0<3
(3,2) - ( arr[2],arr[3] ) 2<3

The approach used in the below program is as follows

We will use two approaches. First naive approach using a for loop. Start traversing array arr[] using two for loops. From i=0 to i<length-1 and j=i+1 to j<length. In this way always i<j. Now add pairs (arr[i],arr[j]) to set<pair<int, int>> se; At the end size of ‘se’ will be the number of unique pairs with i<j.

  • Take integer arrays arr[] with integer elements and length as size

  • Function unique_pair(int arr[], int size) takes array and its length and returns the number of unique pairs such that in pair (arr[i],arr[j]) index i<j

  • Take the initial value of count as 0.

  • Take a set ‘se’ containing integer pairs. (set<pair<int, int>> se)

  • Start traversing arr[] using two for loops. from i=0 to i<size-1 and j=i+1 to j<size.

  • For each pair always i<j, add pair (arr[i],arr[j]) to ‘se’ using se.insert(make_pair(arr[i], arr[j]));

  • At the end of both for loop, update count=se.size().

  • Count now has a number of pairs in ‘se’. ( All are unique ).

  • Return count as result.

Efficient Approach

In this approach, we will find unique elements after each element. arr[i] would pair with distinct/unique elements from arr[ i+1 to size-1 ]. So if there are x unique elements after arr[i], then arr[i] would make x pairs. So we will first make an array marking unique elements after an index i. Then add individual such counts for total unique pairs.

  • Take integer arrays arr[] with integer elements and length as size

  • Function unique_pair(int arr[], int size) takes array and its length and returns the number of unique pairs such that in pair (arr[i],arr[j]) index i<j

  • Take the initial value of count as 0.

  • Take the temp variable and set it to 0.

  • Take an array arr_2[] of length size and initialize arr_2[size-1]=0, as last element has 0 unique elements after it.

  • Create two integer sets check and uncheck.

  • Traverse array from last element to first.i=size-1 to i>=0. Search for arr[i] in set check.

  • If not found then it is unique. Increment temp (temp is count of unique elements after arr[i] ). Set arr_2[i]=temp.

  • Else arr_2[i]=temp. Without increment in temp.

  • Insert arr[i] to set check. Now the next occurrence of arr[i] will not be considered.

  • After the end of this for loop. arr_2[] is updated.

  • Now traverse arr[] from index i=0 to i<size-1. For every arr[i] check if it is in set uncheck. If not then arr[i] occurred the first time, add arr_2[i] ( unique elements after arr[i] ) to count. Else do nothing and continue.

  • Add arr[i] to set uncheck. Now the next occurence of arr[i] will not be considered.

  • At the end count has unique pairs such that i<j for unique pairs (arr[i],arr[j]).

  • Return count as result.

Example (naive approach)

 Live Demo

#include<bits/stdc++.h>
using namespace std;
int unique_pair(int arr[], int size){
   int count = 0;
   set<pair<int, int>> se;
   for(int i = 0; i < (size - 1); i++){
      for (int j = i + 1; j < size; j++){
         se.insert(make_pair(arr[i], arr[j]));
      }
   }
   count = se.size();
   return count;
}
int main(){
   int arr[] = { 4, 3, 1, 6, 7 };
   int size = sizeof(arr) / sizeof(arr[0]);
   cout<<"Count of unique pairs (arr[i], arr[j]) such that i < j are: "<<unique_pair(arr, size);
return 0;
}

Output

If we run the above code it will generate the following output −

Count of unique pairs (arr[i], arr[j]) such that i & j are: 10

Example (efficient approach)

 Live Demo

#include<bits/stdc++.h>
using namespace std;
int unique_pair(int arr[], int size){
   int count = 0, temp = 0;
   int arr_2[size];
   arr_2[size-1] = 0;
   set<int> check, uncheck;
   for (int i = size - 1; i > 0; i--){
      auto set = check.find(arr[i]);
      if (set != check.end()){
         arr_2[i - 1] = temp;
      }
      else{
         arr_2[i - 1] = ++temp;
      }
      check.insert(arr[i]);
   }
   for (int i = 0; i < size - 1; i++){
      auto set = uncheck.find(arr[i]);
      if (set != uncheck.end()){
         continue;
      }
      count += arr_2[i];
      uncheck.insert(arr[i]);
   }
   return count;
}
int main(){
   int arr[] = { 4, 3, 1, 6, 7 };
   int size = sizeof(arr)/sizeof(arr[0]);
   cout<<"Count of unique pairs (arr[i], arr[j]) such that i < j are: "<<unique_pair(arr, size);
   return 0;
}

Output

If we run the above code it will generate the following output −

Count of unique pairs (arr[i], arr[j]) such that i < j are: 10

Updated on: 02-Dec-2020

640 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements