Count Number of Divisible Triplet Sums
Last Updated :
01 May, 2024
Given a 0-indexed integer array arr[] and an integer d, return the count number of triplets (i, j, k) such that i < j < k and (arr[i] + arr[j] + arr[k]) % d == 0.
Example:
Input: arr= [3,3,4,7,8], d = 5
Output: 3
Explanation: The triplets which are divisible by 5 are: (0, 1, 2), (0, 2, 4), (1, 2, 4).
It can be shown that no other triplet is divisible by 5. Hence, the answer is 3.
Input: arr= [3,3,3,3], d = 3
Output: 4
Explanation: Any triplet chosen here has a sum of 9, which is divisible by 3. Hence, the answer is the total number of triplets which is 4.
Approach:
For a number d to divide the sum of a triplet, the sum of their remainders (mod d) must also be divisible by d. In a given array, for each element num[i], we calculate the remainder (modulo d) of every possible pair with the elements between indices 0 and i−1, and store these in a hashmap. We then take the modulo of num[i] and search in the hashmap for a pair that, when combined with num[i], has a sum of remainders divisible by d.
Steps-by-step approach:
- Iterate over the array and calculate the sum of each pair of elements.
- Store the sum of each pair and the corresponding indices of the elements in a hash map.
- Iterate Over the Array
- For each element in the array, calculate the target sum that is congruent to 0 modulo the given divisor.
- Iterate over the pairs of elements that have a sum congruent to the target sum.
- If the indices of the pair are less than the index of the current element, increment the count of divisible triplets.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to count the number of triplets (i, j, k) such
// that i < j < k and (arr[i] + arr[j] + arr[k]) % d == 0
int divisibleTripletCount(vector<int>& arr, int d)
{
// Create a hash map to store the sum of pairs of
// elements and their corresponding indices
unordered_map<int, vector<pair<int, int> > > dupletSums;
// Iterate over the array and calculate the sum of each
// pair of elements
for (int i = 0; i < arr.size(); ++i) {
for (int j = i + 1; j < arr.size(); ++j) {
// Calculate the sum of the pair and store it in
// the hash map along with the indices of the
// elements
dupletSums[(arr[i] + arr[j]) % d].emplace_back(
i, j);
}
}
// Initialize the count of divisible triplets to 0
int ans = 0;
// Iterate over the array again
for (int k = 0; k < arr.size(); ++k) {
// Calculate the target sum that is congruent to 0
// modulo d
int targetKey = (d - arr[k] % d + d) % d;
// Iterate over the pairs of elements that have a
// sum congruent to the target sum
for (const auto& ijPair : dupletSums[targetKey]) {
// Check if the indices of the pair are less
// than the index of the current element
if (ijPair.second < k) {
// Increment the count of divisible triplets
ans++;
}
}
}
// Return the count of divisible triplets
return ans;
}
int main()
{
// Initialize the input array
vector<int> arr = { 1, 2, 3, 4, 5 };
// Initialize the target divisor
int d = 3;
// Call the divisibleTripletCount function to count the
// number of divisible triplets
int count = divisibleTripletCount(arr, d);
// Print the count of divisible triplets
cout << "The number of divisible triplets is: " << count
<< endl;
return 0;
}
Java
import java.util.*;
// Define a simple Pair class to store two values
class Pair<A, B> {
public A first;
public B second;
public Pair(A first, B second)
{
this.first = first;
this.second = second;
}
}
public class Main {
// Function to count the number of triplets (i, j, k)
// such that i < j < k and (arr[i] + arr[j] + arr[k]) %
// d == 0
static int divisibleTripletCount(List<Integer> arr,
int d)
{
// Create a hash map to store the sum of pairs of
// elements and their corresponding indices
Map<Integer, List<Pair<Integer, Integer> > >
dupletSums = new HashMap<>();
// Iterate over the array and calculate the sum of
// each pair of elements
for (int i = 0; i < arr.size(); ++i) {
for (int j = i + 1; j < arr.size(); ++j) {
// Calculate the sum of the pair and store
// it in the hash map along with the indices
// of the elements
int sum = (arr.get(i) + arr.get(j)) % d;
dupletSums
.computeIfAbsent(sum,
k -> new ArrayList<>())
.add(new Pair<>(i, j));
}
}
// Initialize the count of divisible triplets to 0
int ans = 0;
// Iterate over the array again
for (int k = 0; k < arr.size(); ++k) {
// Calculate the target sum that is congruent to
// 0 modulo d
int targetKey = (d - arr.get(k) % d + d) % d;
// Iterate over the pairs of elements that have
// a sum congruent to the target sum
for (Pair<Integer, Integer> ijPair :
dupletSums.getOrDefault(
targetKey, Collections.emptyList())) {
// Check if the indices of the pair are less
// than the index of the current element
if (ijPair.second < k) {
// Increment the count of divisible
// triplets
ans++;
}
}
}
// Return the count of divisible triplets
return ans;
}
public static void main(String[] args)
{
// Initialize the input array
List<Integer> arr = Arrays.asList(1, 2, 3, 4, 5);
// Initialize the target divisor
int d = 3;
// Call the divisibleTripletCount function to count
// the number of divisible triplets
int count = divisibleTripletCount(arr, d);
// Print the count of divisible triplets
System.out.println(
"The number of divisible triplets is: "
+ count);
}
}
// This code is contributed by shivamupta310570
Python
def divisible_triplet_count(arr, d):
# Create a dictionary to store the sum of pairs of
# elements and their corresponding indices
duplet_sums = {}
# Iterate over the array and calculate the sum of each
# pair of elements
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
# Calculate the sum of the pair and store it in
# the dictionary along with the indices of the
# elements
sum_val = (arr[i] + arr[j]) % d
duplet_sums.setdefault(sum_val, []).append((i, j))
# Initialize the count of divisible triplets to 0
count = 0
# Iterate over the array again
for k in range(len(arr)):
# Calculate the target sum that is congruent to 0
# modulo d
target_key = (d - arr[k] % d + d) % d
# Iterate over the pairs of elements that have a
# sum congruent to the target sum
for ij_pair in duplet_sums.get(target_key, []):
# Check if the indices of the pair are less
# than the index of the current element
if ij_pair[1] < k:
# Increment the count of divisible triplets
count += 1
# Return the count of divisible triplets
return count
# Initialize the input array
arr = [1, 2, 3, 4, 5]
# Initialize the target divisor
d = 3
# Call the divisible_triplet_count function to count the
# number of divisible triplets
count = divisible_triplet_count(arr, d)
# Print the count of divisible triplets
print("The number of divisible triplets is:", count)
# this code is contributed by Utkarsh.
OutputThe number of divisible triplets is: 4
Time Complexity: O(n3)
Auxiliary Space: O(n2)
Efficient Approach:
We can use the idea of above solution, instead of precomputing all the (pair sum % d) and store it in some map say dupletSum, we can calculate the same while iterating over each element. Lets assume the index of our valid triplet is (i, j, k) and if we are trying to calculate the valid triplet which are ending at k then we must have all (pair sum % d) before k. So, for current index k, our answer would be (ans += pairSum [expected]).
Steps-by-step approach:
- Create a map dupletSums to store the count of pairs with a pair sum % d
- For each element nums[k]:
- Calculate the expected remainder expected for the current element to form a divisible triplet.
- Add the count of pairs with the expected remainder to the answer ans.
- Iterate over the previous elements (i):
- Calculate the sum x of the current element and the previous element modulo d.
- Increment the count of pairs with the calculated sum x in the dupletSums map.
- Return the count
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to count the number of triplets (i, j, k) such
// that i < j < k and (arr[i] + arr[j] + arr[k]) % d == 0
int divisibleTripletCount(vector<int>& arr, int d)
{
// Initialize variables
int n = arr.size();
int ans = 0;
// Store the count of pairs with a pair sum modulo d
unordered_map<int, int> dupletSums;
// Iterate over the array from the second element to
// the last
for (int k = 1; k < n; k++) {
// Calculate the expected remainder for the
// current element to form a divisible triplet
int expected = (d - (arr[k] % d) + d) % d;
// Add the count of pairs with the expected
// remainder to the answer
ans += dupletSums[expected];
// Iterate over the previous elements
for (int i = 0; i < k; i++) {
// Calculate the sum of the current element
// and the previous element modulo d
int x = (arr[i] + arr[k]) % d;
// Increment the count of pairs with the
// calculated sum in the map
dupletSums[x]++;
}
}
// Return the total count of divisible triplets
return ans;
}
int main()
{
// Initialize the input array
vector<int> arr = { 1, 2, 3, 4, 5 };
// Initialize the target divisor
int d = 3;
// Call the divisibleTripletCount function to count the
// number of divisible triplets
int count = divisibleTripletCount(arr, d);
// Print the count of divisible triplets
cout << "The number of divisible triplets is: " << count
<< endl;
return 0;
}
OutputThe number of divisible triplets is: 4
Time Complexity: O(n2)
Auxiliary Space: O(n2)
Share your thoughts in the comments
Please Login to comment...