Open In App

Count Number of Divisible Triplet Sums

Last Updated : 01 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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.

Output
The 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;
}

Output
The number of divisible triplets is: 4

Time Complexity: O(n2)
Auxiliary Space: O(n2)




Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads