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++
// CPP Program to count pairs in an array
// with some common digit
#include <bits/stdc++.h>
using namespace std;
// Returns true if the pair is valid,
// otherwise false
bool checkValidPair(int num1, int num2)
{
// converting integers to strings
string s1 = to_string(num1);
string s2 = to_string(num2);
// Iterate over the strings and check
// if a character in first string is also
// present in second string, return true
for (int i = 0; i < s1.size(); i++)
for (int j = 0; j < s2.size(); j++)
if (s1[i] == s2[j])
return true;
// No common digit found
return false;
}
// Returns the number of valid pairs
int countPairs(int arr[], int n)
{
int numberOfPairs = 0;
// Iterate over all possible pairs
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
if (checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
// Driver Code to test above functions
int main()
{
int arr[] = { 10, 12, 24 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << countPairs(arr, n) << endl;
return 0;
}
Java
// Java Program to count
// pairs in an array
// with some common digit
import java.io.*;
class GFG
{
// Returns true if the pair
// is valid, otherwise false
static boolean checkValidPair(int num1,
int num2)
{
// converting integers
// to strings
String s1 = Integer.toString(num1);
String s2 = Integer.toString(num2);
// Iterate over the strings
// and check if a character
// in first string is also
// present in second string,
// return true
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;
// No common
// digit found
return false;
}
// Returns the number
// of valid pairs
static int countPairs(int []arr, int n)
{
int numberOfPairs = 0;
// Iterate over all
// possible pairs
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
if (checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
// Driver Code
public static void main(String args[])
{
int []arr = new int[]{ 10, 12, 24 };
int n = arr.length;
System.out.print(countPairs(arr, n));
}
}
// This code is contributed
// by manish shaw.
Python3
# Python3 Program to count pairs in
# an array with some common digit
# Returns true if the pair is
# valid, otherwise false
def checkValidPair(num1, num2) :
# converting integers to strings
s1 = str(num1)
s2 = str(num2)
# Iterate over the strings and check if
# a character in first string is also
# present in second string, return true
for i in range(len(s1)) :
for j in range(len(s2)) :
if (s1[i] == s2[j]) :
return True;
# No common digit found
return False;
# Returns the number of valid pairs
def countPairs(arr, n) :
numberOfPairs = 0
# Iterate over all possible pairs
for i in range(n) :
for j in range(i + 1, n) :
if (checkValidPair(arr[i], arr[j])) :
numberOfPairs += 1
return numberOfPairs
# Driver Code
if __name__ == "__main__" :
arr = [ 10, 12, 24 ]
n = len(arr)
print(countPairs(arr, n))
# This code is contributed by Ryuga
C#
// C# Program to count pairs in an array
// with some common digit
using System;
class GFG {
// Returns true if the pair is valid,
// otherwise false
static bool checkValidPair(int num1, int num2)
{
// converting integers to strings
string s1 = num1.ToString();
string s2 = num2.ToString();
// Iterate over the strings and check
// if a character in first string is also
// present in second string, return true
for (int i = 0; i < s1.Length; i++)
for (int j = 0; j < s2.Length; j++)
if (s1[i] == s2[j])
return true;
// No common digit found
return false;
}
// Returns the number of valid pairs
static int countPairs(int []arr, int n)
{
int numberOfPairs = 0;
// Iterate over all possible pairs
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
if (checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
// Driver Code to test above functions
static void Main()
{
int []arr = new int[]{ 10, 12, 24 };
int n = arr.Length;
Console.WriteLine(countPairs(arr, n));
}
}
// This code is contributed by manish shaw.
PHP
<?php
// PHP Program to count pairs in an array
// with some common digit
// Returns true if the pair is valid,
// otherwise false
function checkValidPair($num1, $num2)
{
// converting integers to strings
$s1 = (string)$num1;
$s2 = (string)$num2;
// Iterate over the strings and check
// if a character in first string is also
// present in second string, return true
for ($i = 0; $i < strlen($s1); $i++)
for ($j = 0; $j < strlen($s2); $j++)
if ($s1[$i] == $s2[$j])
return true;
// No common digit found
return false;
}
// Returns the number of valid pairs
function countPairs(&$arr, $n)
{
$numberOfPairs = 0;
// Iterate over all possible pairs
for ($i = 0; $i < $n; $i++)
for ($j = $i + 1; $j < $n; $j++)
if (checkValidPair($arr[$i],
$arr[$j]))
$numberOfPairs++;
return $numberOfPairs;
}
// Driver Code
$arr = array(10, 12, 24 );
$n = sizeof($arr);
echo (countPairs($arr, $n));
// This code is contributed
// by Shivi_Aggarwal
?>
JavaScript
<script>
// Javascript Program to count pairs in an array
// with some common digit
// Returns true if the pair is valid,
// otherwise false
function checkValidPair(num1, num2)
{
// converting integers to strings
var s1 = num1.toString();
var s2 = num2.toString();
var i,j;
// Iterate over the strings and check
// if a character in first string is also
// present in second string, return true
for(i = 0; i < s1.length; i++)
for(j = 0; j < s2.length; j++)
if (s1[i] == s2[j])
return true;
// No common digit found
return false;
}
// Returns the number of valid pairs
function countPairs(arr, n)
{
var numberOfPairs = 0;
// Iterate over all possible pairs
for(i = 0; i < n; i++)
for(j = i + 1; j < n; j++)
if(checkValidPair(arr[i], arr[j]))
numberOfPairs++;
return numberOfPairs;
}
// Driver Code to test above functions
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++
// CPP Program to count pairs in an array with
// some common digit
#include <bits/stdc++.h>
using namespace std;
// This function calculates the mask frequencies
// for every present in the array
void calculateMaskFrequencies(int arr[], int n,
unordered_map<int, int>& freq)
{
// Iterate over the array
for (int i = 0; i < n; i++) {
int num = arr[i];
// Creating an empty mask
int mask = 0;
// Extracting every digit of the number
// and updating corresponding bit in the
// mask
while (num > 0) {
mask = mask | (1 << (num % 10));
num /= 10;
}
// Update the frequency array
freq[mask]++;
}
}
// Function return the number of valid pairs
int countPairs(int arr[], int n)
{
// Store the mask frequencies
unordered_map<int, int> freq;
calculateMaskFrequencies(arr, n, freq);
long long int numberOfPairs = 0;
// Considering every possible pair of masks
// and calculate pairs according to their
// frequencies
for (int i = 0; i < 1024; i++) {
numberOfPairs += (freq[i] * (freq[i] - 1)) / 2;
for (int j = i + 1; j < 1024; j++) {
// if it contains a common digit
if (i & j)
numberOfPairs += (freq[i] * freq[j]);
}
}
return numberOfPairs;
}
// Driver Code to test above functions
int main()
{
int arr[] = { 10, 12, 24 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << countPairs(arr, n) << endl;
return 0;
}
Java
// Java Program to count pairs in an array with
// some common digit
import java.io.*;
import java.util.*;
class GFG
{
// Store the mask frequencies
public static Map<Integer, Integer> freq = new HashMap<Integer, Integer>();
// This function calculates the mask frequencies
// for every present in the array
public static void calculateMaskFrequencies(int[] arr,int n)
{
// Iterate over the array
for(int i = 0; i < n; i++)
{
int num = arr[i];
// Creating an empty mask
int mask = 0;
// Extracting every digit of the number
// and updating corresponding bit in the
// mask
while(num > 0)
{
mask = mask | (1 << (num % 10));
num /= 10;
}
// Update the frequency array
if(freq.containsKey(mask))
{
freq.put(new Integer(mask), freq.get(mask) + 1);
}
else
{
freq.put(new Integer(mask), 1);
}
}
}
// Function return the number of valid pairs
public static int countPairs(int[] arr, int n)
{
calculateMaskFrequencies(arr, n);
int numberOfPairs = 0;
// Considering every possible pair of masks
// and calculate pairs according to their
// frequencies
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 it contains a common digit
if((i & j) != 0)
{
if(freq.containsKey(j))
{
y = freq.get(j);
}
numberOfPairs += x * y;
}
}
}
return numberOfPairs;
}
// Driver Code
public static void main (String[] args)
{
int[] arr = {10, 12, 24};
int n = arr.length;
System.out.println(countPairs(arr, n));
}
}
// This code is contributed by avanitrachhadiya2155
Python3
# Python3 Program to count pairs in an array
# with some common digit
# This function calculates the mask frequencies
# for every present in the array
def calculateMaskFrequencies(arr, n, freq):
# Iterate over the array
for i in range(n):
num = arr[i]
# Creating an empty mask
mask = 0
# Extracting every digit of the number
# and updating corresponding bit in the
# mask
while (num > 0):
mask = mask | (1 << (num % 10))
num //= 10
# Update the frequency array
freq[mask] = freq.get(mask, 0) + 1
# Function return the number of valid pairs
def countPairs(arr, n):
# Store the mask frequencies
freq = dict()
calculateMaskFrequencies(arr, n, freq)
numberOfPairs = 0
# Considering every possible pair of masks
# and calculate pairs according to their
# frequencies
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 it contains a common digit
if (i & j):
numberOfPairs += (x * y)
return numberOfPairs
# Driver Code
arr = [10, 12, 24]
n = len(arr)
print(countPairs(arr, n))
# This code is contributed by mohit kumar
C#
// C# Program to count pairs in an array with
// some common digit
using System;
using System.Collections.Generic;
public class GFG
{
// Store the mask frequencies
static Dictionary<int, int> freq = new Dictionary<int, int>();
// This function calculates the mask frequencies
// for every present in the array
public static void calculateMaskFrequencies(int[] arr,int n)
{
// Iterate over the array
for(int i = 0; i < n; i++)
{
int num = arr[i];
// Creating an empty mask
int mask = 0;
// Extracting every digit of the number
// and updating corresponding bit in the
// mask
while(num > 0)
{
mask = mask | (1 << (num % 10));
num /= 10;
}
// Update the frequency array
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;
// Considering every possible pair of masks
// and calculate pairs according to their
// frequencies
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 it contains a common digit
if((i & j) != 0)
{
if(freq.ContainsKey(j))
{
y = freq[j];
}
numberOfPairs += x * y;
}
}
}
return numberOfPairs;
}
// Driver Code
static public void Main ()
{
int[] arr = {10, 12, 24};
int n = arr.Length;
Console.WriteLine(countPairs(arr, n));
}
}
// This code is contributed by rag2127
JavaScript
<script>
// Javascript Program to count pairs in an array with
// some common digit
// Store the mask frequencies
let freq = new Map();
// This function calculates the mask frequencies
// for every present in the array
function calculateMaskFrequencies(arr,n)
{
// Iterate over the array
for(let i = 0; i < n; i++)
{
let num = arr[i];
// Creating an empty mask
let mask = 0;
// Extracting every digit of the number
// and updating corresponding bit in the
// mask
while(num > 0)
{
mask = mask | (1 << (num % 10));
num = Math.floor(num/10);
}
// Update the frequency array
if(freq.has(mask))
{
freq.set((mask), freq.get(mask) + 1);
}
else
{
freq.set((mask), 1);
}
}
}
// Function return the number of valid pairs
function countPairs(arr,n)
{
calculateMaskFrequencies(arr, n);
let numberOfPairs = 0;
// Considering every possible pair of masks
// and calculate pairs according to their
// frequencies
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 it contains a common digit
if((i & j) != 0)
{
if(freq.has(j))
{
y = freq.get(j);
}
numberOfPairs += x * y;
}
}
}
return numberOfPairs;
}
// Driver Code
let arr=[10, 12, 24];
let n = arr.length;
document.write(countPairs(arr, n));
// This code is contributed by unknown2108
</script>
Time Complexity: O(N + 1024 * 1024), where N is the size of the array.
Space Complexity : O( 1 )
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem