Given an array arr[] and positive integer k, the task is to count total number of pairs in the array whose sum is divisible by k.
Examples:
Input: arr[] = {2, 2, 1, 7, 5, 3}, k = 4
Output: 5
Explanation: There are five pairs possible whose sum is divisible by '4' ,
i.e., (2, 2), (1, 7), (7, 5), (1, 3) and (5, 3)
Input: arr[] = {5, 9, 36, 74, 52, 31, 42}, k = 3
Output: 7
Explanation: There are seven pairs whose sum is divisible by 3,
i.e, (9, 36), (9,42), (74, 52), (36, 42), (74, 31), (31, 5) and (5, 52).
Table of Content
[Naive Approach] Using Two Loops - O(n2) Time O(1) Space
The idea is to run two nested loops to consider all possible pairs in the array. For each pair, we check whether If the condition (arr[i] + arr[j]) % k == 0 is satisfied, we increment the count.
#include <bits/stdc++.h>
using namespace std;
int countKdivPairs(vector<int> &arr, int k)
{
// variable for storing answer
int res = 0;
for (int i = 0; i < arr.size(); i++) {
for (int j = i + 1; j < arr.size(); j++) {
// if pair sum is divisible
int sum = arr[i] + arr[j];
if (sum % k == 0)
// Increment res
res++;
}
}
return res;
}
// Driver code
int main()
{
vector<int> arr = {2, 2, 1, 7, 5, 3};
int k = 4;
cout << countKdivPairs(arr, k);
return 0;
}
#include <stdio.h>
int countKdivPairs(int arr[], int n, int k)
{
// variable for storing answer
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// if pair sum is divisible
if ((arr[i] + arr[j]) % k == 0)
// Increment res
res++;
}
}
return res;
}
// Driver code
int main()
{
int arr[] = {2, 2, 1, 7, 5, 3};
int k = 4;
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d", countKdivPairs(arr, n, k));
return 0;
}
import java.util.*;
public class GfG {
static int countKdivPairs(int[] arr, int k) {
// variable for storing answer
int res = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
// if pair sum is divisible
if ((arr[i] + arr[j]) % k == 0)
// Increment res
res++;
}
}
return res;
}
// Driver code
public static void main(String[] args) {
int[] arr = {2, 2, 1, 7, 5, 3};
int k = 4;
System.out.println(countKdivPairs(arr, k));
}
}
# Function to count pairs whose sum is divisible by k
def countKdivPairs(arr, k):
# variable for storing answer
res = 0
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
# if pair sum is divisible
if (arr[i] + arr[j]) % k == 0:
# Increment res
res += 1
return res
# Driver code
if __name__ == "__main__":
arr = [2, 2, 1, 7, 5, 3]
k = 4
print(countKdivPairs(arr, k))
using System;
class GfG
{
static int countKdivPairs(int[] arr, int k)
{
// variable for storing answer
int res = 0;
for (int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
// if pair sum is divisible
if ((arr[i] + arr[j]) % k == 0)
{
// Increment count
res++;
}
}
}
return res;
}
static void Main()
{
int[] arr = { 2, 2, 1, 7, 5, 3 };
int k = 4;
Console.WriteLine(countKdivPairs(arr, k));
}
}
function countKdivPairs(arr, k) {
// variable for storing answer
let res = 0;
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
// if pair sum is divisible
if ((arr[i] + arr[j]) % k == 0)
// Increment res
res++;
}
}
return res;
}
// Driver code
let arr = [2, 2, 1, 7, 5, 3];
let k = 4;
console.log(countKdivPairs(arr, k));
Output
5
Time Complexity: O(n2)
Space Complexity: O(1)
[Expected Approach] Using Hashing - O(n + k) Time O(k) Space
The idea is to use a frequency map to count elements based on their remainders when divided by k. Then, pairs are formed by combining remainders i and k - i. Handle remainder 0 separately, and if k is even, also handle k/2.
Let us understand with an example:
Input: arr[] = [2, 2, 1, 7, 5, 3], k = 4
Step 1: Initialize res = 0
Step 2: Build Frequency Map for Remainders
freq{2} = 2 [For 2 & 2]
freq{1} = 2 [For 1 and 5}
freq{3} = {2} [For 7 and 3]
Step 3: Check if there are elements with 0 remainder, we need to add freq{0} * (freq{0} - 1)/2 to the result because every item can form a pair with every other item.
No items with zero remainder in our input example [2, 2, 1, 7, 5, 3] and k = 4
Step 3: Run a loop for i = 1 to k/2 and i is not same as k - i (to avoid counting same number twice)
i = 1: Add freq{1} * freq{4-1} to the result, we get res = res + 2*2 = 0 + 4 = 4
i = 2: Since k - i == i, we break the loop
Step 4: If k is even and freq{k/2} is not zero then we need to count pairs avoiding double counting.
k = 4 and it is even, so we add freq{k/2} * (freq{k/2} - 1)/2 to the result, res = res + (2*(2-1))/2 = 4 + 1 = 5.
All pairs processed. final result = 5
#include <bits/stdc++.h>
using namespace std;
// Program to count pairs whose sum divisible
// by k
int countKdivPairs(vector<int> &arr, int k)
{
// Create a frequency array to count
// occurrences of all remainders when
// divided by k
vector<int> freq(k, 0);
// Count occurrences of all remainders
for (int i = 0; i < arr.size(); i++)
++freq[arr[i] % k];
// If both pairs are divisible by 'k'
int res = freq[0] * (freq[0] - 1) / 2;
// count for all i and (k-i)
// freq pairs
for (int i = 1; i <= k / 2 && i!= (k - i); i++)
res += freq[i] * freq[k - i];
// If k is even
if (k % 2 == 0)
res += (freq[k / 2] * (freq[k / 2] - 1) / 2);
return res;
}
// Driver code
int main()
{
vector<int> arr = {2, 2, 1, 7, 5, 3};
int k = 4;
cout << countKdivPairs(arr, k);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
// Program to count pairs whose sum divisible by k
int countKdivPairs(int arr[], int n, int k)
{
int freq[k];
// Initialize frequency array
for (int i = 0; i < k; i++)
freq[i] = 0;
// Count occurrences of remainders
for (int i = 0; i < n; i++)
++freq[arr[i] % k];
int res = freq[0] * (freq[0] - 1) / 2;
for (int i = 1; i <= k / 2 && i!= (k - i); i++)
res += freq[i] * freq[k - i];
if (k % 2 == 0)
res += (freq[k / 2] * (freq[k / 2] - 1) / 2);
return res;
}
// Driver code
int main()
{
int arr[] = {2, 2, 1, 7, 5, 3};
int n = sizeof(arr) / sizeof(arr[0]);
int k = 4;
printf("%d", countKdivPairs(arr, n, k));
return 0;
}
import java.util.Arrays;
// Program to count pairs whose sum divisible
// by k
public class GfG {
static int countKdivPairs(int[] arr, int k) {
// Create a frequency array to count
// occurrences of all remainders when
// divided by k
int[] freq = new int[k];
Arrays.fill(freq, 0);
// Count occurrences of all remainders
for (int i = 0; i < arr.length; i++)
++freq[arr[i] % k];
// If both pairs are divisible by 'k'
int res = freq[0] * (freq[0] - 1) / 2;
// count for all i and (k-i)
// freq pairs
for (int i = 1; i <= k / 2 && i!= (k - i); i++)
res += freq[i] * freq[k - i];
// If k is even
if (k % 2 == 0)
res += (freq[k / 2] * (freq[k / 2] - 1) / 2);
return res;
}
// Driver code
public static void main(String[] args) {
int[] arr = {2, 2, 1, 7, 5, 3};
int k = 4;
System.out.println(countKdivPairs(arr, k));
}
}
# Program to count pairs whose sum divisible
# by k
def countKdivPairs(arr, k):
# Create a frequency array to count
# occurrences of all remainders when
# divided by k
freq = [0] * k
# Count occurrences of all remainders
for i in range(len(arr)):
freq[arr[i] % k] += 1
# If both pairs are divisible by 'k'
res = freq[0] * (freq[0] - 1) // 2
# count for all i and (k-i)
# freq pairs
for i in range(1, k // 2 + 1):
if i!= (k - i):
res += freq[i] * freq[k - i]
# If k is even
if k % 2 == 0:
res += (freq[k // 2] * (freq[k // 2] - 1) // 2)
return res
# Driver code
if __name__ == "__main__":
arr = [2, 2, 1, 7, 5, 3]
k = 4
print(countKdivPairs(arr, k))
using System;
using System.Collections.Generic;
class GfG
{
// Program to count pairs whose sum divisible
// by k
static int countKdivPairs(int[] arr, int k)
{
// Create a frequency array to count
// occurrences of all remainders when
// divided by k
int[] freq = new int[k];
// Count occurrences of all remainders
for (int i = 0; i < arr.Length; i++)
++freq[arr[i] % k];
// If both pairs are divisible by 'k'
int res = freq[0] * (freq[0] - 1) / 2;
// count for all i and (k-i)
// freq pairs
for (int i = 1; i <= k / 2 && i!= (k - i); i++)
res += freq[i] * freq[k - i];
// If k is even
if (k % 2 == 0)
res += (freq[k / 2] * (freq[k / 2] - 1) / 2);
return res;
}
// Driver code
static void Main()
{
int[] arr = { 2, 2, 1, 7, 5, 3 };
int k = 4;
Console.WriteLine(countKdivPairs(arr, k));
}
}
function countKdivPairs(arr, k) {
// Create a frequency array to count
// occurrences of all remainders when
// divided by k
let freq = new Array(k).fill(0);
// Count occurrences of all remainders
for (let i = 0; i < arr.length; i++) {
freq[arr[i] % k]++;
}
// If both pairs are divisible by 'k'
let res = freq[0] * (freq[0] - 1) / 2;
// count for all i and (k-i)
// freq pairs
for (let i = 1; i <= k / 2 && i!= (k - i); i++) {
res += freq[i] * freq[k - i];
}
// If k is even
if (k % 2 === 0) {
res += (freq[k / 2] * (freq[k / 2] - 1) / 2);
}
return res;
}
// Driver code
let arr = [2, 2, 1, 7, 5, 3];
let k = 4;
console.log(countKdivPairs(arr, k));
Output
5
Time Complexity: O(n + k)
Space Complexity: O(k)