Given an array of positive integers arr[], count the number of triangles that can be formed with three different array elements as three sides of triangles.
Note: The sum of any two sides of a triangle must be greater than the third side.
Examples:
Input: arr[] = [4, 6, 3, 7]
Output: 3
Explanation: There are three triangles possible [3, 4, 6], [4, 6, 7] and [3, 6, 7].
Note that [3, 4, 7] is not a possible triangle.Input: arr[] = [10, 21, 22, 100, 101, 200, 300]
Output: 6
Explanation: There can be 6 possible triangles:
[10, 21, 22], [21, 100, 101], [22, 100, 101], [10, 100, 101], [100, 101, 200] and [101, 200, 300]Input: arr[] = [1, 2, 3]
Output: 0
Examples: No triangles are possible.
Table of Content
[Naive Approach] Checking all Triplets - O(n^3) Time and O(1) Space
A simple approach is to run three nested loops that select three different values from an array. And in the innermost loop, we checks for the triangle property which specifies the sum of any two sides must be greater than the value of the third side.
#include <iostream>
#include <vector>
using namespace std;
int countTriangles(vector<int>& arr) {
int res = 0;
// The three loops select three
// different values from array
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++)
// Sum of two sides is greater than the third
if (arr[i] + arr[j] > arr[k] &&
arr[i] + arr[k] > arr[j] &&
arr[k] + arr[j] > arr[i])
res++;
}
}
return res;
}
int main() {
vector<int> arr = {4, 6, 3, 7};
cout << countTriangles(arr);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int countTriangles(int arr[], int n) {
int res = 0;
// The three loops select three
// different values from array
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++)
// Sum of two sides is greater than the third
if (arr[i] + arr[j] > arr[k] &&
arr[i] + arr[k] > arr[j] &&
arr[k] + arr[j] > arr[i])
res++;
}
}
return res;
}
int main() {
int arr[] = {4, 6, 3, 7};
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d", countTriangles(arr, n));
return 0;
}
import java.util.ArrayList;
class GFG {
static int countTriangles(int[] arr) {
int res = 0;
// The three loops select three
// different values from array
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++) {
// Sum of two sides is greater than the third
if (arr[i] + arr[j] > arr[k] &&
arr[i] + arr[k] > arr[j] &&
arr[k] + arr[j] > arr[i]) {
res++;
}
}
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {4, 6, 3, 7};
System.out.println(countTriangles(arr));
}
}
def countTriangles(arr):
res = 0
# The three loops select three
# different values from array
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
for k in range(j + 1, len(arr)):
# Sum of two sides is greater than the third
if arr[i] + arr[j] > arr[k] and \
arr[i] + arr[k] > arr[j] and \
arr[k] + arr[j] > arr[i]:
res += 1
return res
if __name__ == "__main__":
arr = [4, 6, 3, 7]
print(countTriangles(arr))
using System;
class GFG {
static int countTriangles(int[] arr) {
int res = 0;
// The three loops select three
// different values from array
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++) {
// Sum of two sides is greater than the third
if (arr[i] + arr[j] > arr[k] &&
arr[i] + arr[k] > arr[j] &&
arr[k] + arr[j] > arr[i]) {
res++;
}
}
}
}
return res;
}
static void Main(string[] args) {
int[] arr = { 4, 6, 3, 7 };
Console.WriteLine(countTriangles(arr));
}
}
function countTriangles(arr) {
let res = 0;
// The three loops select three
// different values from array
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++) {
// Sum of two sides is greater than the third
if (arr[i] + arr[j] > arr[k] &&
arr[i] + arr[k] > arr[j] &&
arr[k] + arr[j] > arr[i]) {
res++;
}
}
}
}
return res;
}
// Driver Code
const arr = [4, 6, 3, 7];
console.log(countTriangles(arr));
Output
3
[Better Approach] Using Binary Search - O((n^2)*log n) Time and O(1) Space
The idea is to first sort the array in ascending order. Then, use two nested loops where the outer loop fixes the first side and the inner loop fixes the second side. For each such pair, perform a binary search to find the farthest valid index for the third side (with an index greater than the first two) whose value is less than the sum of the first two sides. This gives a valid range of choices for the third side that satisfies the required condition. Finally, add the size of this range to the result.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int countTriangles(vector<int> &arr) {
int res = 0;
// Sort the array to apply the
// triangle inequality efficiently
sort(arr.begin(), arr.end());
// Iterate through pairs of sides (arr[i], arr[j])
for (int i = 0; i < arr.size(); i++) {
for (int j = i + 1; j < arr.size(); j++) {
// Find the first index where the
// sum of two sides is not valid
int k = lower_bound(arr.begin() + j + 1, arr.end(), arr[i] + arr[j])
- arr.begin();
// Count the number of valid third sides
int cnt = k - j - 1;
res += cnt;
}
}
return res;
}
int main() {
vector<int> arr = {4, 6, 3, 7};
cout << countTriangles(arr);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
// Comparison function for qsort
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
// Lower bound function to find the first index
// where the sum of two sides is not valid
int lower_bound(int arr[], int n, int value, int start) {
int left = start, right = n;
while (left < right) {
int mid = left + (right - left) / 2;
if (arr[mid] < value)
left = mid + 1;
else
right = mid;
}
return left;
}
// Function to count the number of valid triangles.
int countTriangles(int arr[], int n) {
int res = 0;
// Sort the array to apply the
// triangle inequality efficiently
qsort(arr, n, sizeof(int), compare);
// Iterate through pairs of sides (arr[i], arr[j])
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Find the first index where the
// sum of two sides is not valid
int k = lower_bound(arr, n, arr[i] + arr[j], j + 1);
// Count the number of valid third sides
int cnt = k - j - 1;
res += cnt;
}
}
return res;
}
int main() {
int arr[] = {4, 6, 3, 7};
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", countTriangles(arr, n));
return 0;
}
import java.util.Arrays;
class GFG {
static int countTriangles(int[] arr) {
int res = 0;
// Sort the array to apply the
// triangle inequality efficiently
Arrays.sort(arr);
// Iterate through pairs of sides (arr[i], arr[j])
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
// Find the first index where the
// sum of two sides is not valid
int lo = j + 1, hi = arr.length;
int target = arr[i] + arr[j];
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] < target) {
lo = mid + 1;
} else {
hi = mid;
}
}
// Count the number of valid third sides
int cnt = lo - j - 1;
res += cnt;
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {4, 6, 3, 7};
System.out.println(countTriangles(arr));
}
}
from bisect import bisect_left
def countTriangles(arr):
res = 0
# Sort the array to apply the
# triangle inequality efficiently
arr.sort()
# Iterate through pairs of sides (arr[i], arr[j])
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
# Find the first index where the
# sum of two sides is not valid
k = bisect_left(arr, arr[i] + arr[j], j + 1)
# Count the number of valid third sides
cnt = k - j - 1
res += cnt
return res
if __name__ == "__main__":
arr = [4, 6, 3, 7]
print(countTriangles(arr))
using System;
using System.Linq;
class GFG {
static int countTriangles(int[] arr) {
int res = 0;
// Sort the array to apply the
// triangle inequality efficiently
Array.Sort(arr);
// Iterate through pairs of sides (arr[i], arr[j])
for (int i = 0; i < arr.Length; i++) {
for (int j = i + 1; j < arr.Length; j++) {
// Find the first index where the
// sum of two sides is not valid
int lo = j + 1, hi = arr.Length;
int target = arr[i] + arr[j];
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] < target) {
lo = mid + 1;
} else {
hi = mid;
}
}
// Count the number of valid third sides
int cnt = lo - j - 1;
res += cnt;
}
}
return res;
}
static void Main(string[] args) {
int[] arr = { 4, 6, 3, 7 };
Console.WriteLine(countTriangles(arr));
}
}
function countTriangles(arr) {
let res = 0;
// Sort the array to apply the
// triangle inequality efficiently
arr.sort((a, b) => a - b);
// Iterate through pairs of sides (arr[i], arr[j])
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
// Use binary search to find the first index
// where the sum of two sides is not valid
let lo = j + 1, hi = arr.length;
while (lo < hi) {
let mid = Math.floor((lo + hi) / 2);
if (arr[mid] < arr[i] + arr[j]) {
lo = mid + 1;
} else {
hi = mid;
}
}
// Count the number of valid third sides
let cnt = lo - (j + 1);
res += cnt;
}
}
return res;
}
// Driver Code
const arr = [4, 6, 3, 7];
console.log(countTriangles(arr));
Output
3
[Expected Approach] Using Two Pointers Technique - O(n^2) Time and O(1) Space
Sort the array so the largest side can be fixed, then use two pointers to efficiently count all pairs of smaller sides that satisfy the triangle inequality.
- Sort the array in non-decreasing order.
- Fix each element as the largest side, starting from the end.
- Initialize two pointers: left = 0 and right = i - 1.
- If arr[left] + arr[right] > arr[i], then all pairs from left to right - 1 with right are valid. Add right - left to the count and move right left.
- Otherwise, move left right to increase the sum.
- Repeat until left >= right and return the total count.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int countTriangles(vector<int> &arr) {
int res = 0;
sort(arr.begin(), arr.end());
// Iterate through the array, fixing
// the largest side at arr[i]
for (int i = 2; i < arr.size(); ++i) {
// Initialize pointers for the two smaller sides
int left = 0, right = i - 1;
while (left < right) {
if (arr[left] + arr[right] > arr[i]) {
// arr[left] + arr[right] satisfies
// the triangle inequality, so all pairs
// (x, right) with (left <= x < right) are valid
res += right - left;
// Move the right pointer to check smaller pairs
right--;
}
else {
// Move the left pointer to increase the sum
left++;
}
}
}
return res;
}
int main() {
vector<int> arr = {4, 6, 3, 7};
cout << countTriangles(arr);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
// Function to compare two integers for qsort
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
// Function to count the number of valid triangles
int countTriangles(int arr[], int n) {
int res = 0;
qsort(arr, n, sizeof(int), compare);
// Iterate through the array, fixing
// the largest side at arr[i]
for (int i = 2; i < n; ++i) {
// Initialize pointers for the two smaller sides
int left = 0, right = i - 1;
while (left < right) {
if (arr[left] + arr[right] > arr[i]) {
// arr[left] + arr[right] satisfies the triangle inequality,
// so all pairs (x, right) with (left <= x < right) are valid
res += right - left;
// Move the right pointer to check smaller pairs
right--;
} else {
// Move the left pointer to increase the sum
left++;
}
}
}
return res;
}
int main() {
int arr[] = {4, 6, 3, 7};
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", countTriangles(arr, n));
return 0;
}
import java.util.Arrays;
class GFG {
static int countTriangles(int[] arr) {
int res = 0;
Arrays.sort(arr);
// Iterate through the array, fixing
// the largest side at arr[i]
for (int i = 2; i < arr.length; ++i) {
// Initialize pointers for the two smaller sides
int left = 0, right = i - 1;
while (left < right) {
if (arr[left] + arr[right] > arr[i]) {
// arr[left] + arr[right] satisfies the
// triangle inequality,so all pairs (x, right)
// with (left <= x < right) are valid
res += right - left;
// Move the right pointer to check smaller pairs
right--;
} else {
// Move the left pointer to increase the sum
left++;
}
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {4, 6, 3, 7};
System.out.println(countTriangles(arr));
}
}
def countTriangles(arr):
res = 0
arr.sort()
# Iterate through the array, fixing
# the largest side at arr[i]
for i in range(2, len(arr)):
# Initialize pointers for the two smaller sides
left, right = 0, i - 1
while left < right:
if arr[left] + arr[right] > arr[i]:
# arr[left] + arr[right] satisfies the triangle inequality,
# so all pairs (x, right) with (left <= x < right) are valid
res += right - left
# Move the right pointer to check smaller pairs
right -= 1
else:
# Move the left pointer to increase the sum
left += 1
return res
if __name__ == "__main__":
arr = [4, 6, 3, 7]
print(countTriangles(arr))
using System;
class GFG {
static int countTriangles(int[] arr) {
int res = 0;
Array.Sort(arr);
// Iterate through the array, fixing
// the largest side at arr[i]
for (int i = 2; i < arr.Length; ++i) {
// Initialize pointers for the two smaller sides
int left = 0, right = i - 1;
while (left < right) {
if (arr[left] + arr[right] > arr[i]) {
// arr[left] + arr[right] satisfies the
// triangle inequality, so all pairs (x, right)
// with (left <= x < right) are valid
res += right - left;
// Move the right pointer to check smaller pairs
right--;
} else {
// Move the left pointer to increase the sum
left++;
}
}
}
return res;
}
static void Main(string[] args) {
int[] arr = {4, 6, 3, 7};
Console.WriteLine(countTriangles(arr));
}
}
function countTriangles(arr) {
let res = 0;
arr.sort((a, b) => a - b);
// Iterate through the array, fixing
// the largest side at arr[i]
for (let i = 2; i < arr.length; ++i) {
// Initialize pointers for the two smaller sides
let left = 0, right = i - 1;
while (left < right) {
if (arr[left] + arr[right] > arr[i]) {
// arr[left] + arr[right] satisfies the
// triangle inequality, so all pairs pairs
// (x, right) with (left <= x < right) are valid
res += right - left;
// Move the right pointer to check smaller pairs
right--;
} else {
// Move the left pointer to increase the sum
left++;
}
}
}
return res;
}
// Driver Code
const arr = [4, 6, 3, 7];
console.log(countTriangles(arr));
Output
3