Given an array arr[], count the number of distinct triplets (a, b, c) such that:
- a + b = c
- Each triplet is counted only once, regardless of the order of
aandb.
Examples:
Input: arr[] = [1, 5, 3, 2]
Output: 2
Explanation: There are two such triplets such that sum of the two numbers is equal to the third number, those are (1, 2, 3), (3, 2, 5)Input: arr[] = [3, 2, 7]
Output: 0
Explanation: There are no such triplets such that sum of two numbers is equal to the third number.
We have already discussed, how to Check for Triplet with One as Sum of other Two. In this article, we are going to focus on approaches to count triplets.
Table of Content
[Naive Approach] Generating all triplets - O(n3 log n) time and O(n2) space
Generate all triplets (arr[i], arr[j], arr[k]) such that i < j < k. For each triplet, check if arr[i] + arr[j] == arr[k] and Store valid triplets in a set to ensure uniqueness and return its size.
Algorithm:
- Sort the array to make to make comparisons easy as only the third element can be sum of the other two.
- Run loop for
ifrom0ton-1(first element). - Run loop for
jfromi+1ton-1(second element). - Run loop for
kfromj+1ton-1(third element). - Check if
arr[i] + arr[j] == arr[k]. - If true, check if triplet
{arr[i], arr[j], arr[k]}is not in set. If not present, insert it into the set. - After all loops, return the size of the set as the result.
#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
int countTriplet(vector<int> &arr)
{
// to store unique triplets
set<vector<int>> st;
sort(arr.begin(), arr.end());
// Exploring all triplet
for (int i = 0; i < arr.size(); i++)
{
for (int j = i + 1; j < arr.size(); j++)
{
for (int k = j + 1; k < arr.size(); k++)
{
// Check if sum of two elements equals the third
if (arr[i] + arr[j] == arr[k])
{
// If this triplet is not already present in set
if (st.find({arr[i], arr[j], arr[k]}) == st.end())
{
// Insert the triplet into set
st.insert({arr[i], arr[j], arr[k]});
}
}
}
}
}
return st.size();
}
// Driver Code
int main()
{
vector<int> arr = {1, 5, 3, 2};
cout << countTriplet(arr);
return 0;
}
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
// Function to compare elements for qsort
int compare(const void *a, const void *b)
{
return (*(int *)a - *(int *)b);
}
// Function to check if an array is already in the set
bool contains(int set[][3], int size, int arr[3])
{
for (int i = 0; i < size; i++)
{
if (set[i][0] == arr[0] && set[i][1] == arr[1] && set[i][2] == arr[2])
{
return true;
}
}
return false;
}
int countTriplet(int arr[], int n)
{
// to store unique triplets
int tripletSet[100][3] = {0};
int setSize = 0;
qsort(arr, n, sizeof(int), compare);
// Exploring all triplet
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
for (int k = j + 1; k < n; k++)
{
// Check if sum of two elements equals the third
if (arr[i] + arr[j] == arr[k])
{
int newTriplet[3] = {arr[i], arr[j], arr[k]};
// If this triplet is not already present in set
if (!contains(tripletSet, setSize, newTriplet))
{
// Insert the triplet into set
for (int l = 0; l < 3; l++)
{
tripletSet[setSize][l] = newTriplet[l];
}
setSize++;
}
}
}
}
}
return setSize;
}
int main()
{
int arr[] = {1, 5, 3, 2};
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", countTriplet(arr, n));
return 0;
}
import java.util.*;
public class GfG {
static int countTriplet(int[] arr)
{
// to store unique triplets
Set<List<Integer> > st = new HashSet<>();
Arrays.sort(arr);
// Exploring all triplet
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
for (int k = j + 1; k < arr.length; k++) {
// Check if sum of two elements equals
// the third
if (arr[i] + arr[j] == arr[k]) {
List<Integer> triplet
= Arrays.asList(arr[i], arr[j],
arr[k]);
// If this triplet is not already
// present in set
if (!st.contains(triplet)) {
// Insert the triplet into set
st.add(triplet);
}
}
}
}
}
return st.size();
}
public static void main(String[] args)
{
int[] arr = { 1, 5, 3, 2 };
System.out.println(countTriplet(arr));
}
}
from typing import List
def countTriplet(arr):
# to store unique triplets
st = set()
arr.sort()
# Exploring all triplet
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
for k in range(j + 1, len(arr)):
# Check if sum of two elements equals the third
if arr[i] + arr[j] == arr[k]:
# If this triplet is not already present in set
if (arr[i], arr[j], arr[k]) not in st:
# Insert the triplet into set
st.add((arr[i], arr[j], arr[k]))
return len(st)
#Driver Code
arr = [1, 5, 3, 2]
print(countTriplet(arr))
using System;
using System.Collections.Generic;
public class GfG {
public static int countTriplet(int[] arr) {
// to store unique triplets
HashSet<Tuple<int, int, int>> st = new HashSet<Tuple<int, int, int>>();
Array.Sort(arr);
//Exploring all triplet
for(int i = 0; i < arr.Length; i++){
for(int j = i + 1; j < arr.Length; j++){
for(int k = j + 1; k < arr.Length; k++){
// Check if sum of two elements equals the third
if(arr[i] + arr[j] == arr[k]){
// If this triplet is not already present in set
if(!st.Contains(new Tuple<int, int, int>(arr[i], arr[j], arr[k]))){
// Insert the triplet into set
st.Add(new Tuple<int, int, int>(arr[i], arr[j], arr[k]));
}
}
}
}
}
return st.Count;
}
public static void Main() {
int[] arr = {1, 5, 3, 2};
Console.WriteLine(countTriplet(arr));
}
}
function countTriplet(arr) {
// to store unique triplets
let st = new Set();
arr.sort((a, b) => a - b);
//Exploring all triplet
for(let i = 0; i < arr.length; i++){
for(let j = i + 1; j < arr.length; j++){
for(let k = j + 1; k < arr.length; k++){
// Check if sum of two elements equals the third
if(arr[i] + arr[j] == arr[k]){
let triplet = [arr[i], arr[j], arr[k]].toString();
// If this triplet is not already present in set
if(!st.has(triplet)){
// Insert the triplet into set
st.add(triplet);
}
}
}
}
}
return st.size;
}
//Driver Code
let arr = [1, 5, 3, 2];
console.log(countTriplet(arr));
Output
2
[Expected Approach] Using Sorting + Two Pointer Approach - O(n2) Time O(1) Space
The idea is to Sort the array and Fix one element from the end and use two pointers (one at the start and one before the fixed element) to find pairs whose sum equals the fixed element and Move pointers based on comparison and skip duplicates to avoid repeated triplets.
Instead of checking all triplets (O(n³ log n)), we reduce the problem to a 2-sum problem using two pointers.
#include <vector>
#include <algorithm>
using namespace std;
int countTriplet(vector<int>& arr) {
int n = arr.size();
// if less than 3 elements, no triplets possible.
if (n < 3)
return 0;
sort(arr.begin(), arr.end());
int count = 0;
// Iterating over the array in reverse order (fixing the third element).
for (int k = n - 1; k >= 2; k--) {
// Skipping duplicate values for the third element.
if (k < n - 1 && arr[k] == arr[k + 1])
continue;
int i = 0, j = k - 1;
// Using two-pointer approach to find the triplets.
while (i < j) {
int sum = arr[i] + arr[j];
// If the given condition is satisfied, increment the count and skip
// duplicates.
if (sum == arr[k]) {
count++;
int a = arr[i], b = arr[j];
// Skipping duplicates for left pointer.
while (i < j && arr[i] == a)
i++;
// Skipping duplicates for right pointer.
while (i < j && arr[j] == b)
j--;
}
// If the sum is less than the target, move the left pointer.
else if (sum < arr[k])
i++;
// If the sum is greater than the target, move the right pointer.
else
j--;
}
}
return count;
}
// Driver code
int main() {
vector<int> arr = {1, 5, 3, 2};
cout << countTriplet(arr);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
// Comparator function for integers
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
// Function to count triplets
int countTriplet(int arr[], int n) {
// if less than 3 elements, no triplets possible.
if (n < 3)
return 0;
// Sorting the array
qsort(arr, n, sizeof(int), compare);
int count = 0;
// Iterating over the array in reverse order (fixing the third element).
for (int k = n - 1; k >= 2; k--) {
// Skipping duplicate values for the third element.
if (k < n - 1 && arr[k] == arr[k + 1])
continue;
int i = 0, j = k - 1;
// Using two-pointer approach to find the triplets.
while (i < j) {
int sum = arr[i] + arr[j];
// If the given condition is satisfied, increment the count and skip
// duplicates.
if (sum == arr[k]) {
count++;
int a = arr[i], b = arr[j];
// Skipping duplicates for left and right pointer.
while (i < j && arr[i] == a) i++;
while (i < j && arr[j] == b) j--;
}
// If the sum is less than the target, move the left pointer.
else if (sum < arr[k])
i++;
// If the sum is greater than the target, move the right pointer.
else
j--;
}
}
return count;
}
// Driver code
int main() {
int arr[] = {1, 5, 3, 2};
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d", countTriplet(arr, n));
return 0;
}
import java.util.Arrays;
public class GfG {
// Function to count triplets
static int countTriplet(int[] arr) {
int n = arr.length;
// if less than 3 elements, no triplets possible.
if (n < 3)
return 0;
Arrays.sort(arr);
int count = 0;
// Iterating over the array in reverse order (fixing the third element).
for (int k = n - 1; k >= 2; k--) {
// Skipping duplicate values for the third element.
if (k < n - 1 && arr[k] == arr[k + 1])
continue;
int i = 0, j = k - 1;
// Using two-pointer approach to find the triplets.
while (i < j) {
int sum = arr[i] + arr[j];
// If the given condition is satisfied, increment the count and skip
// duplicates.
if (sum == arr[k]) {
count++;
int a = arr[i], b = arr[j];
// Skipping duplicates for left pointer.
while (i < j && arr[i] == a)
i++;
// Skipping duplicates for right pointer.
while (i < j && arr[j] == b)
j--;
}
// If the sum is less than the target, move the left pointer.
else if (sum < arr[k])
i++;
// If the sum is greater than the target, move the right pointer.
else
j--;
}
}
return count;
}
// Driver code
public static void main(String[] args) {
int[] arr = {1, 5, 3, 2};
System.out.println(countTriplet(arr));
}
}
def countTriplet(arr):
n = len(arr)
# if less than 3 elements, no triplets possible.
if n < 3:
return 0
arr.sort()
count = 0
# Iterating over the array in reverse order (fixing the third element).
for k in range(n - 1, 1, -1):
# Skipping duplicate values for the third element.
if k < n - 1 and arr[k] == arr[k + 1]:
continue
i, j = 0, k - 1
# Using two-pointer approach to find the triplets.
while i < j:
sum = arr[i] + arr[j]
# If the given condition is satisfied, increment the count and skip
# duplicates.
if sum == arr[k]:
count += 1
a, b = arr[i], arr[j]
# Skipping duplicates for left pointer.
while i < j and arr[i] == a:
i += 1
# Skipping duplicates for right pointer.
while i < j and arr[j] == b:
j -= 1
# If the sum is less than the target, move the left pointer.
elif sum < arr[k]:
i += 1
# If the sum is greater than the target, move the right pointer.
else:
j -= 1
return count
# Driver code
arr = [1, 5, 3, 2]
print(countTriplet(arr))
using System;
using System.Linq;
public class GfG
{
// Function to count triplets
public static int countTriplet(int[] arr)
{
int n = arr.Length;
// if less than 3 elements, no triplets possible.
if (n < 3)
return 0;
Array.Sort(arr);
int count = 0;
// Iterating over the array in reverse order (fixing the third element).
for (int k = n - 1; k >= 2; k--)
{
// Skipping duplicate values for the third element.
if (k < n - 1 && arr[k] == arr[k + 1])
continue;
int i = 0, j = k - 1;
// Using two-pointer approach to find the triplets.
while (i < j)
{
int sum = arr[i] + arr[j];
// If the given condition is satisfied, increment the count and skip
// duplicates.
if (sum == arr[k])
{
count++;
int a = arr[i], b = arr[j];
// Skipping duplicates for left pointer.
while (i < j && arr[i] == a)
i++;
// Skipping duplicates for right pointer.
while (i < j && arr[j] == b)
j--;
}
// If the sum is less than the target, move the left pointer.
else if (sum < arr[k])
i++;
// If the sum is greater than the target, move the right pointer.
else
j--;
}
}
return count;
}
// Driver code
public static void Main()
{
int[] arr = { 1, 5, 3, 2 };
Console.WriteLine(countTriplet(arr));
}
}
class Solution {
countTriplet(arr) {
let n = arr.length;
// if less than 3 elements, no triplets possible.
if (n < 3)
return 0;
arr.sort((a, b) => a - b);
let count = 0;
// Iterating over the array in reverse order (fixing the third element).
for (let k = n - 1; k >= 2; k--) {
// Skipping duplicate values for the third element.
if (k < n - 1 && arr[k] === arr[k + 1])
continue;
let i = 0, j = k - 1;
// Using two-pointer approach to find the triplets.
while (i < j) {
let sum = arr[i] + arr[j];
// If the given condition is satisfied, increment the count and skip
// duplicates.
if (sum === arr[k]) {
count++;
let a = arr[i], b = arr[j];
// Skipping duplicates for left pointer.
while (i < j && arr[i] === a)
i++;
// Skipping duplicates for right pointer.
while (i < j && arr[j] === b)
j--;
}
// If the sum is less than the target, move the left pointer.
else if (sum < arr[k])
i++;
// If the sum is greater than the target, move the right pointer.
else
j--;
}
}
return count;
}
}
// Driver code
let obj = new Solution();
let arr = [1, 5, 3, 2];
console.log(obj.countTriplet(arr));
Output
2