Count pairs (p, q) such that p occurs in array at least q times and q occurs at least p times

Given an array arr[], the task is to count unordered pairs of positive integers (p, q) such that p occurs in the array at least q times and q occurs at least p times.

Examples:

Input: arr[] = {1, 2, 3, 4, 5}
Output: 1
(1, 1) is the only valid pair

Input: arr[] = {3, 3, 2, 2, 2}
Output: 2
(2, 3) and (2, 2) are the only possible pairs.

Approach:

  1. The idea is to hash every element of array with its count and create a vector of unique elements from the array elements. Initialize number of pairs to 0.
  2. Loop through the vector of unique elements to count the number of pairs.
  3. Inside the loop if count of element is less than the element itself then continue else if count of element is equal to the element then increment the number of pairs by 1 (Pair of the form (x, x)) else go to Step 4.
  4. Increment number of pairs by 1 and loop from j = (element + 1) to count of the element updating j by 1 if count of j is greater than or equal to element then increment number of pairs by 1 as the pairs are unordered.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the count of required pairs
int get_unordered_pairs(int a[], int n)
{
    // To store unique elements
    vector<int> vs;
  
    // To hash elements with their frequency
    unordered_map<int, int> m;
  
    // Store frequencies in m and all distinct
    // items in vs
    for (int i = 0; i < n; i++) {
        m[a[i]]++;
        if (m[a[i]] == 1)
            vs.push_back(a[i]);
    }
  
    // Traverse through distinct elements
    int number_of_pairs = 0;
    for (int i = 0; i < vs.size(); i++) {
  
        // If current element is greater than
        // its frequency in the array
        if (m[vs[i]] < vs[i])
            continue;
  
        // If element is equal to its frequency,
        // a pair of the form (x, x) is formed.
        else if (m[vs[i]] == vs[i])
            number_of_pairs += 1;
  
        // If element is less than its frequency
        else {
            number_of_pairs += 1;
            for (int j = vs[i] + 1; j <= m[vs[i]]; j++) {
                if (m[j] >= vs[i])
                    number_of_pairs += 1;
            }
        }
    }
    return number_of_pairs;
}
  
// Driver code
int main()
{
    int arr[] = { 3, 3, 2, 2, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << get_unordered_pairs(arr, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{
      
// Function to return the count of required pairs
static int get_unordered_pairs(int []a, int n)
{
    // To store unique elements
    ArrayList<Integer> vs = new ArrayList<Integer>();
  
    // To hash elements with their frequency
    int[] m = new int[maximum(a)+1];
  
    // Store frequencies in m and all distinct
    // items in vs
    for (int i = 0; i < n; i++) 
    {
        m[(int)a[i]]++;
        if (m[a[i]] == 1)
            vs.add(a[i]);
    }
  
    // Traverse through distinct elements
    int number_of_pairs = 0;
    for (int i = 0; i < vs.size(); i++) 
    {
  
        // If current element is greater than
        // its frequency in the array
        if (m[(int)vs.get(i)] < (int)vs.get(i))
            continue;
  
        // If element is equal to its frequency,
        // a pair of the form (x, x) is formed.
        else if (m[(int)vs.get(i)] == (int)vs.get(i))
            number_of_pairs += 1;
  
        // If element is less than its frequency
        else
        {
            number_of_pairs += 1;
            for (int j = (int)vs.get(i) + 1; j <= m[(int)vs.get(i)]; j++)
            {
                if (m[j] >= (int)vs.get(i))
                    number_of_pairs += 1;
            }
        }
    }
    return number_of_pairs;
}
static int maximum(int []arr)
{
    int max = Integer.MIN_VALUE;
    for(int i = 0; i < arr.length; i++)
    {
        if(arr[i] > max)
        {
            max = arr[i];
        }
    }
    return max;
}
  
// Driver code
public static void main (String[] args) 
{
  
    int []arr = { 3, 3, 2, 2, 2 };
    int n = arr.length;
    System.out.println(get_unordered_pairs(arr, n));
}
}
  
// This code is contributed by mits

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
from collections import defaultdict
  
# Function to return the count of 
# required pairs 
def get_unordered_pairs(a, n): 
  
    # To store unique elements 
    vs = [] 
  
    # To hash elements with their frequency 
    m = defaultdict(lambda:0
  
    # Store frequencies in m and 
    # all distinct items in vs 
    for i in range(0, n): 
        m[a[i]] += 1
        if m[a[i]] == 1
            vs.append(a[i]) 
  
    # Traverse through distinct elements 
    number_of_pairs = 0
    for i in range(0, len(vs)): 
  
        # If current element is greater 
        # than its frequency in the array 
        if m[vs[i]] < vs[i]:
            continue
  
        # If element is equal to its frequency, 
        # a pair of the form (x, x) is formed. 
        elif m[vs[i]] == vs[i]: 
            number_of_pairs += 1
  
        # If element is less than its
        # frequency 
        else:
            number_of_pairs += 1
            for j in range(vs[i] + 1, m[vs[i]] + 1): 
                if m[j] >= vs[i]: 
                    number_of_pairs += 1
      
    return number_of_pairs 
  
# Driver code 
if __name__ == "__main__"
  
    arr = [3, 3, 2, 2, 2
    n = len(arr) 
    print(get_unordered_pairs(arr, n))
  
# This code is contributed
# by Rituraj Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections;
using System.Linq;
  
class GFG
{
// Function to return the count of required pairs
static int get_unordered_pairs(int []a, int n)
{
    // To store unique elements
    ArrayList vs = new ArrayList();
  
    // To hash elements with their frequency
    int[] m = new int[a.Max()+1];
  
    // Store frequencies in m and all distinct
    // items in vs
    for (int i = 0; i < n; i++) 
    {
        m[(int)a[i]]++;
        if (m[a[i]] == 1)
            vs.Add(a[i]);
    }
  
    // Traverse through distinct elements
    int number_of_pairs = 0;
    for (int i = 0; i < vs.Count; i++) 
    {
  
        // If current element is greater than
        // its frequency in the array
        if (m[(int)vs[i]] < (int)vs[i])
            continue;
  
        // If element is equal to its frequency,
        // a pair of the form (x, x) is formed.
        else if (m[(int)vs[i]] == (int)vs[i])
            number_of_pairs += 1;
  
        // If element is less than its frequency
        else 
        {
            number_of_pairs += 1;
            for (int j = (int)vs[i] + 1; j <= m[(int)vs[i]]; j++)
            {
                if (m[j] >= (int)vs[i])
                    number_of_pairs += 1;
            }
        }
    }
    return number_of_pairs;
}
  
// Driver code
static void Main()
{
    int []arr = { 3, 3, 2, 2, 2 };
    int n = arr.Length;
    Console.WriteLine(get_unordered_pairs(arr, n));
}
}
  
// This code is contributed by mits

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach 
  
// Function to return the count of 
// required pairs 
function get_unordered_pairs($a, $n
    // To store unique elements 
    $vs = array(); 
  
    // To hash elements with 
    // their frequency 
    $m = array();
      
    for($i = 0; $i < $n; $i++)
        $m[$a[$i]] = 0 ;
      
  
    // Store frequencies in m and 
    // all distinct items in vs 
    for ($i = 0; $i < $n; $i++)
    
        $m[$a[$i]]++; 
        if ($m[$a[$i]] == 1) 
            array_push($vs, $a[$i]); 
    
  
    // Traverse through distinct elements 
    $number_of_pairs = 0; 
    for ($i = 0; $i < sizeof($vs); $i++) 
    
  
        // If current element is greater 
        // than its frequency in the array 
        if ($m[$vs[$i]] < $vs[$i]) 
            continue
  
        // If element is equal to its frequency, 
        // a pair of the form (x, x) is formed. 
        else if ($m[$vs[$i]] == $vs[$i]) 
            $number_of_pairs += 1; 
  
        // If element is less than its 
        // frequency 
        else
        
            $number_of_pairs += 1; 
            for ($j = $vs[$i] + 1; 
                 $j <= $m[$vs[$i]]; $j++) 
            {
                if ($m[$j] >= $vs[$i]) 
                    $number_of_pairs += 1; 
            
        
    
    return $number_of_pairs
  
// Driver code 
$arr = array(3, 3, 2, 2, 2); 
$n = sizeof($arr);
echo get_unordered_pairs($arr, $n); 
  
// This code is contributed by Ryuga
?>

chevron_right


Output:

2


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.





Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.