Count of pairs in an array whose product is a perfect square
Last Updated :
24 Apr, 2023
Given an array arr[] of N integers, the task is to find the number of pairs (arr[i], arr[j]) such that arr[i]*arr[j] is a perfect square.
Examples:
Input: arr[] = { 1, 2, 4, 8, 5, 6}
Output: 2
Explanation:
The pairs such that the product of an element is perfectly square are (1, 4) and (8, 2).
Input: arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
Output: 4
Explanation:
The pairs such that the product of an element is perfectly square are (1, 4), (1, 9), (2, 8) and (4, 9).
Naive Approach:
Run two loops from 1 to n and count all the pairs (i, j) where arr[i]*arr[j] is a perfect square. The time complexity of this approach will be O(N2).
C++
#include <bits/stdc++.h>
using namespace std;
bool checkperfectsquare( int n)
{
if ( ceil (( double ) sqrt (n)) == floor (( double ) sqrt (n))) {
return true ;
}
else {
return false ;
}
}
int countPairs( int arr[], int n)
{
int count = 0;
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
if (checkperfectsquare(arr[i] * arr[j])) {
count++;
}
}
}
return count;
}
int main()
{
int arr[] = { 1, 2, 4, 8, 5, 6 };
int n = sizeof (arr) / sizeof ( int );
cout << countPairs(arr, n) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
static boolean checkperfectsquare( int n)
{
if (Math.ceil(( double )Math.sqrt(n))
== Math.floor(( double )Math.sqrt(n))) {
return true ;
}
else {
return false ;
}
}
static int countPairs( int arr[], int n)
{
int count = 0 ;
for ( int i = 0 ; i < n; i++) {
for ( int j = i + 1 ; j < n; j++) {
if (checkperfectsquare(arr[i] * arr[j])) {
count++;
}
}
}
return count;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 4 , 8 , 5 , 6 };
int n = arr.length;
System.out.println(countPairs(arr, n));
}
}
|
Python3
import math
def checkperfectsquare(n):
if math.ceil(math.sqrt(n)) = = math.floor(math.sqrt(n)):
return True
else :
return False
def countPairs(arr, n):
count = 0
for i in range (n):
for j in range (i + 1 , n):
if checkperfectsquare(arr[i] * arr[j]):
count + = 1
return count
if __name__ = = '__main__' :
arr = [ 1 , 2 , 4 , 8 , 5 , 6 ]
n = len (arr)
print (countPairs(arr, n))
|
Javascript
function checkperfectsquare(n) {
if (Math.ceil(Math.sqrt(n)) == Math.floor(Math.sqrt(n))) {
return true ;
}
else {
return false ;
}
}
function countPairs(arr, n) {
let count = 0;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if (checkperfectsquare(arr[i] * arr[j])) {
count++;
}
}
}
return count;
}
let arr = [1, 2, 4, 8, 5, 6];
let n = arr.length;
console.log(countPairs(arr, n));
|
C#
using System;
public class MainClass {
public static bool CheckPerfectSquare( int n)
{
if (Math.Ceiling(Math.Sqrt(n))
== Math.Floor(Math.Sqrt(n))) {
return true ;
}
else {
return false ;
}
}
public static int CountPairs( int [] arr, int n)
{
int count = 0;
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
if (CheckPerfectSquare(arr[i] * arr[j])) {
count += 1;
}
}
}
return count;
}
public static void Main( string [] args)
{
int [] arr = { 1, 2, 4, 8, 5, 6 };
int n = arr.Length;
Console.WriteLine(CountPairs(arr, n));
}
}
|
Time Complexity : O(n^2) // since two nested loops are used the time taken by the algorithm to complete all operation is quadratic.
Space Complexity : O(1) // since no extra array is used so the space taken by the algorithm is constant
Efficient Approach:
Each integer in arr[] can be represented in the following form:
arr[i] = k*x ..............(1)
where k is not divisible by any perfect square other than 1,
and x = perfect square,
Steps:
- Represent every element in the form of equation(1).
- Then, for every pair (arr[i], arr[j]) in arr[] can be represented as:
arr[i] = ki*x;
arr[j] = kj*y;
where x and y are perfect square
- For pairs (arr[i], arr[j]), the product of arr[i] and arr[j] can be perfectly square if and only if ki = kj
- Use Sieve of Eratosthenes to pre-compute the value of k for every element in array arr[].
- Store the frequency of k for every element in arr[] in map.
- Therefore, the total number of pairs is given by the number of pairs formed by elements with a frequency greater than 1.
- The total number of pairs formed by n elements is given by:
Number of Pairs = (f*(f-1))/2
where f is the frequency of an element.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int prime[100001] = { 0 };
int k[100001] = { 0 };
void Sieve()
{
for ( int i = 1; i < 100001; i++)
k[i] = i;
for ( int i = 2; i < 100001; i++) {
if (prime[i] == 0)
for ( int j = i; j < 100001; j += i) {
prime[j] = 1;
while (k[j] % (i * i) == 0)
k[j] /= (i * i);
}
}
}
int countPairs( int arr[], int n)
{
unordered_map< int , int > freq;
for ( int i = 0; i < n; i++) {
freq[k[arr[i]]]++;
}
int sum = 0;
for ( auto i : freq) {
sum += ((i.second - 1) * i.second) / 2;
}
return sum;
}
int main()
{
int arr[] = { 1, 2, 4, 8, 5, 6 };
int n = sizeof (arr) / sizeof ( int );
Sieve();
cout << countPairs(arr, n) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int []prime = new int [ 100001 ];
static int []k = new int [ 100001 ];
static void Sieve()
{
for ( int i = 1 ; i < 100001 ; i++)
k[i] = i;
for ( int i = 2 ; i < 100001 ; i++) {
if (prime[i] == 0 )
for ( int j = i; j < 100001 ; j += i) {
prime[j] = 1 ;
while (k[j] % (i * i) == 0 )
k[j] /= (i * i);
}
}
}
static int countPairs( int arr[], int n)
{
HashMap<Integer,Integer> freq = new HashMap<Integer,Integer>();
for ( int i = 0 ; i < n; i++) {
if (freq.containsKey(k[arr[i]])) {
freq.put(k[arr[i]], freq.get(k[arr[i]])+ 1 );
}
else
freq.put(k[arr[i]], 1 );
}
int sum = 0 ;
for (Map.Entry<Integer,Integer> i : freq.entrySet()){
sum += ((i.getValue() - 1 ) * i.getValue()) / 2 ;
}
return sum;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 4 , 8 , 5 , 6 };
int n = arr.length;
Sieve();
System.out.print(countPairs(arr, n) + "\n" );
}
}
|
Python3
prime = [ 0 ] * 100001
k = [ 0 ] * 100001
def Sieve():
for i in range ( 1 , 100001 ):
k[i] = i
for i in range ( 2 , 100001 ):
if (prime[i] = = 0 ):
for j in range (i, 100001 , i):
prime[j] = 1
while (k[j] % (i * i) = = 0 ):
k[j] / = (i * i)
def countPairs (arr, n):
freq = dict ()
for i in range (n):
if k[arr[i]] in freq.keys():
freq[k[arr[i]]] + = 1
else :
freq[k[arr[i]]] = 1
Sum = 0
for i in freq:
Sum + = (freq[i] * (freq[i] - 1 )) / 2
return Sum
arr = [ 1 , 2 , 4 , 8 , 5 , 6 ]
n = len (arr)
Sieve()
print ( int (countPairs(arr, n)))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int []prime = new int [100001];
static int []k = new int [100001];
static void Sieve()
{
for ( int i = 1; i < 100001; i++)
k[i] = i;
for ( int i = 2; i < 100001; i++) {
if (prime[i] == 0)
for ( int j = i; j < 100001; j += i) {
prime[j] = 1;
while (k[j] % (i * i) == 0)
k[j] /= (i * i);
}
}
}
static int countPairs( int []arr, int n)
{
Dictionary< int , int > freq = new Dictionary< int , int >();
for ( int i = 0; i < n; i++) {
if (freq.ContainsKey(k[arr[i]])) {
freq[k[arr[i]]] = freq[k[arr[i]]]+1;
}
else
freq.Add(k[arr[i]], 1);
}
int sum = 0;
foreach (KeyValuePair< int , int > i in freq){
sum += ((i.Value - 1) * i.Value) / 2;
}
return sum;
}
public static void Main(String[] args)
{
int []arr = { 1, 2, 4, 8, 5, 6 };
int n = arr.Length;
Sieve();
Console.Write(countPairs(arr, n) + "\n" );
}
}
|
Javascript
<script>
let prime = new Array(100001).fill(0);
let k = new Array(100001).fill(0);
function Sieve()
{
for (let i = 1; i < 100001; i++)
k[i] = i;
for (let i = 2; i < 100001; i++) {
if (prime[i] == 0)
for (let j = i; j < 100001; j += i) {
prime[j] = 1;
while (k[j] % (i * i) == 0)
k[j] /= (i * i);
}
}
}
function countPairs(arr, n)
{
let freq = new Map();
for (let i = 0; i < n; i++) {
if (freq.has(k[arr[i]])) {
freq.set(k[arr[i]], freq.get(k[arr[i]])+1);
}
else
freq.set(k[arr[i]], 1);
}
let sum = 0;
for (let i of freq) {
sum += ((i[1] - 1) * i[1]) / 2;
}
return sum;
}
let arr = [ 1, 2, 4, 8, 5, 6 ];
let n = arr.length;
Sieve();
document.write(countPairs(arr, n) + "<br>" );
</script>
|
Time Complexity: O(N*log(log N)), since sieve of Eratosthenes takes N *log(log N) time to execute
Auxiliary Space: O(N + 105)
Share your thoughts in the comments
Please Login to comment...