Count pairs in an array which have at least one digit common
Last Updated :
08 Mar, 2023
Given an array of N numbers. Find out the number of pairs i and j such that i < j and Ai and Aj have at least one digit common (For e.g. (11, 19) have 1 digit common but (36, 48) have no digit common)
Examples:
Input: A[] = { 10, 12, 24 }
Output: 2
Explanation: Two valid pairs are (10, 12) and (12, 24) which have atleast one digit common
Method 1 (Brute Force):
A naive approach to solve this problem is just by running two nested loops and consider all possible pairs. We can check if the two numbers have at least one common digit, by extracting every digit of the first number and try to find it in the extracted digits of second number. The task would become much easier we simply convert them into strings.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool checkValidPair( int num1, int num2)
{
string s1 = to_string(num1);
string s2 = to_string(num2);
for ( int i = 0; i < s1.size(); i++)
for ( int j = 0; j < s2.size(); j++)
if (s1[i] == s2[j])
return true ;
return false ;
}
int countPairs( int arr[], int n)
{
int numberOfPairs = 0;
for ( int i = 0; i < n; i++)
for ( int j = i + 1; j < n; j++)
if (checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
int main()
{
int arr[] = { 10, 12, 24 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << countPairs(arr, n) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG
{
static boolean checkValidPair( int num1,
int num2)
{
String s1 = Integer.toString(num1);
String s2 = Integer.toString(num2);
for ( int i = 0 ; i < s1.length(); i++)
for ( int j = 0 ; j < s2.length(); j++)
if (s1.charAt(i) == s2.charAt(j))
return true ;
return false ;
}
static int countPairs( int []arr, int n)
{
int numberOfPairs = 0 ;
for ( int i = 0 ; i < n; i++)
for ( int j = i + 1 ; j < n; j++)
if (checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
public static void main(String args[])
{
int []arr = new int []{ 10 , 12 , 24 };
int n = arr.length;
System.out.print(countPairs(arr, n));
}
}
|
Python3
def checkValidPair(num1, num2) :
s1 = str (num1)
s2 = str (num2)
for i in range ( len (s1)) :
for j in range ( len (s2)) :
if (s1[i] = = s2[j]) :
return True ;
return False ;
def countPairs(arr, n) :
numberOfPairs = 0
for i in range (n) :
for j in range (i + 1 , n) :
if (checkValidPair(arr[i], arr[j])) :
numberOfPairs + = 1
return numberOfPairs
if __name__ = = "__main__" :
arr = [ 10 , 12 , 24 ]
n = len (arr)
print (countPairs(arr, n))
|
C#
using System;
class GFG {
static bool checkValidPair( int num1, int num2)
{
string s1 = num1.ToString();
string s2 = num2.ToString();
for ( int i = 0; i < s1.Length; i++)
for ( int j = 0; j < s2.Length; j++)
if (s1[i] == s2[j])
return true ;
return false ;
}
static int countPairs( int []arr, int n)
{
int numberOfPairs = 0;
for ( int i = 0; i < n; i++)
for ( int j = i + 1; j < n; j++)
if (checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
static void Main()
{
int []arr = new int []{ 10, 12, 24 };
int n = arr.Length;
Console.WriteLine(countPairs(arr, n));
}
}
|
PHP
<?php
function checkValidPair( $num1 , $num2 )
{
$s1 = (string) $num1 ;
$s2 = (string) $num2 ;
for ( $i = 0; $i < strlen ( $s1 ); $i ++)
for ( $j = 0; $j < strlen ( $s2 ); $j ++)
if ( $s1 [ $i ] == $s2 [ $j ])
return true;
return false;
}
function countPairs(& $arr , $n )
{
$numberOfPairs = 0;
for ( $i = 0; $i < $n ; $i ++)
for ( $j = $i + 1; $j < $n ; $j ++)
if (checkValidPair( $arr [ $i ],
$arr [ $j ]))
$numberOfPairs ++;
return $numberOfPairs ;
}
$arr = array (10, 12, 24 );
$n = sizeof( $arr );
echo (countPairs( $arr , $n ));
?>
|
Javascript
<script>
function checkValidPair(num1, num2)
{
var s1 = num1.toString();
var s2 = num2.toString();
var i,j;
for (i = 0; i < s1.length; i++)
for (j = 0; j < s2.length; j++)
if (s1[i] == s2[j])
return true ;
return false ;
}
function countPairs(arr, n)
{
var numberOfPairs = 0;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++)
if (checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
var arr = [10, 12, 24];
var n = arr.length;;
document.write(countPairs(arr, n));
</script>
|
Time Complexity: O(N2) where N is the size of array.
Space Complexity : O( 1 )
Method 2 (Bit Masking):
An efficient approach of solving this problem is creating a bit mask for every digit present in a particular number. Thus, for every digit to be present in a number if we have a mask of 1111111111.
Digits - 0 1 2 3 4 5 6 7 8 9
| | | | | | | | | |
Mask - 1 1 1 1 1 1 1 1 1 1
Here 1 denotes that the corresponding ith digit is set.
For e.g. 1235 can be represented as
Digits - 0 1 2 3 4 5 6 7 8 9
| | | | | | | | | |
Mask for 1235 - 0 1 1 1 0 1 0 0 0 0
Now we just have to extract every digit of a number and make the corresponding bit set (1 << ith digit) and store the whole number as a mask. Careful analysis suggests that the maximum value of the mask is 1023 in decimal (which contains all the digits from 0 – 9). Since the same set of digits can exist in more than one number, we need to maintain a frequency array to store the count of mask value.
Let the frequencies of two masks i and j be freqi and freqj respectively,
If(i AND j) return true, means ith and jth mask contains atleast one common set bit which in turn implies that the numbers from which these masks have been built also contain a common digit
then,
increment the answer
ans += freqi * freqj [ if i != j ]
ans += (freqi * (freqi – 1)) / 2 [ if j == i ]
Below is the implementation of this efficient approach:
C++
#include <bits/stdc++.h>
using namespace std;
void calculateMaskFrequencies( int arr[], int n,
unordered_map< int , int >& freq)
{
for ( int i = 0; i < n; i++) {
int num = arr[i];
int mask = 0;
while (num > 0) {
mask = mask | (1 << (num % 10));
num /= 10;
}
freq[mask]++;
}
}
int countPairs( int arr[], int n)
{
unordered_map< int , int > freq;
calculateMaskFrequencies(arr, n, freq);
long long int numberOfPairs = 0;
for ( int i = 0; i < 1024; i++) {
numberOfPairs += (freq[i] * (freq[i] - 1)) / 2;
for ( int j = i + 1; j < 1024; j++) {
if (i & j)
numberOfPairs += (freq[i] * freq[j]);
}
}
return numberOfPairs;
}
int main()
{
int arr[] = { 10, 12, 24 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << countPairs(arr, n) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
public static Map<Integer, Integer> freq = new HashMap<Integer, Integer>();
public static void calculateMaskFrequencies( int [] arr, int n)
{
for ( int i = 0 ; i < n; i++)
{
int num = arr[i];
int mask = 0 ;
while (num > 0 )
{
mask = mask | ( 1 << (num % 10 ));
num /= 10 ;
}
if (freq.containsKey(mask))
{
freq.put( new Integer(mask), freq.get(mask) + 1 );
}
else
{
freq.put( new Integer(mask), 1 );
}
}
}
public static int countPairs( int [] arr, int n)
{
calculateMaskFrequencies(arr, n);
int numberOfPairs = 0 ;
for ( int i = 0 ; i < 1024 ; i++)
{
int x = 0 ;
if (freq.containsKey(i))
{
x = freq.get(i);
}
numberOfPairs += ((x) * (x - 1 )) / 2 ;
for ( int j = i + 1 ; j < 1024 ; j++)
{
int y = 0 ;
if ((i & j) != 0 )
{
if (freq.containsKey(j))
{
y = freq.get(j);
}
numberOfPairs += x * y;
}
}
}
return numberOfPairs;
}
public static void main (String[] args)
{
int [] arr = { 10 , 12 , 24 };
int n = arr.length;
System.out.println(countPairs(arr, n));
}
}
|
Python3
def calculateMaskFrequencies(arr, n, freq):
for i in range (n):
num = arr[i]
mask = 0
while (num > 0 ):
mask = mask | ( 1 << (num % 10 ))
num / / = 10
freq[mask] = freq.get(mask, 0 ) + 1
def countPairs(arr, n):
freq = dict ()
calculateMaskFrequencies(arr, n, freq)
numberOfPairs = 0
for i in range ( 1024 ):
x = 0
if i in freq.keys():
x = freq[i]
numberOfPairs + = (x * (x - 1 )) / / 2
for j in range (i + 1 , 1024 ):
y = 0
if j in freq.keys():
y = freq[j]
if (i & j):
numberOfPairs + = (x * y)
return numberOfPairs
arr = [ 10 , 12 , 24 ]
n = len (arr)
print (countPairs(arr, n))
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static Dictionary< int , int > freq = new Dictionary< int , int >();
public static void calculateMaskFrequencies( int [] arr, int n)
{
for ( int i = 0; i < n; i++)
{
int num = arr[i];
int mask = 0;
while (num > 0)
{
mask = mask | (1 << (num % 10));
num /= 10;
}
if (freq.ContainsKey(mask))
{
freq[mask]++;
}
else
{
freq.Add(mask, 1);
}
}
}
public static int countPairs( int [] arr, int n)
{
calculateMaskFrequencies(arr, n);
int numberOfPairs = 0;
for ( int i = 0; i < 1024; i++)
{
int x = 0;
if (freq.ContainsKey(i))
{
x = freq[i];
}
numberOfPairs += ((x) * (x - 1)) / 2;
for ( int j = i + 1; j < 1024; j++)
{
int y = 0;
if ((i & j) != 0)
{
if (freq.ContainsKey(j))
{
y = freq[j];
}
numberOfPairs += x * y;
}
}
}
return numberOfPairs;
}
static public void Main ()
{
int [] arr = {10, 12, 24};
int n = arr.Length;
Console.WriteLine(countPairs(arr, n));
}
}
|
Javascript
<script>
let freq = new Map();
function calculateMaskFrequencies(arr,n)
{
for (let i = 0; i < n; i++)
{
let num = arr[i];
let mask = 0;
while (num > 0)
{
mask = mask | (1 << (num % 10));
num = Math.floor(num/10);
}
if (freq.has(mask))
{
freq.set((mask), freq.get(mask) + 1);
}
else
{
freq.set((mask), 1);
}
}
}
function countPairs(arr,n)
{
calculateMaskFrequencies(arr, n);
let numberOfPairs = 0;
for (let i = 0; i < 1024; i++)
{
let x = 0;
if (freq.has(i))
{
x = freq.get(i);
}
numberOfPairs += Math.floor((x) * (x - 1)) / 2;
for (let j = i + 1; j < 1024; j++)
{
let y = 0;
if ((i & j) != 0)
{
if (freq.has(j))
{
y = freq.get(j);
}
numberOfPairs += x * y;
}
}
}
return numberOfPairs;
}
let arr=[10, 12, 24];
let n = arr.length;
document.write(countPairs(arr, n));
</script>
|
Time Complexity: O(N + 1024 * 1024), where N is the size of the array.
Space Complexity : O( 1 )
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...