Given an integer array arr[] and an integer x, determine whether there exist four distinct elements in the array whose sum is equal to x. Return true if such four elements exist. Otherwise, return false.
Examples:
Input: arr[] = [1, 5, 1, 0, 6, 0], x = 7
Output: true
Explanation: The four elements 1, 5, 1, 0 have a sum equal to 7.Input: arr[] = [1, 2, 3, 4, 5], x = 50
Output: false
Explanation: No combination of four distinct elements has a sum equal to 50.
Table of Content
[Naive Approach] Checking Every Quadruplet - O(n ^ 4) Time and O(1) Space
The idea is to generate every possible combination of four distinct indices and check whether the sum of their elements is equal to x. If any quadruplet has the required sum, return true. Otherwise, return false.
#include <iostream>
#include <vector>
using namespace std;
bool fourSum(vector<int>& arr, int x) {
int n = arr.size();
// Check every possible quadruplet.
for (int i = 0; i < n - 3; i++) {
for (int j = i + 1; j < n - 2; j++) {
for (int k = j + 1; k < n - 1; k++) {
for (int l = k + 1; l < n; l++) {
if (arr[i] + arr[j] + arr[k] + arr[l] == x) {
return true;
}
}
}
}
}
return false;
}
int main() {
vector<int> arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
cout << boolalpha << fourSum(arr1, x1) << endl;
vector<int> arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
cout << boolalpha << fourSum(arr2, x2) << endl;
return 0;
}
class GFG {
static boolean fourSum(int[] arr, int x) {
int n = arr.length;
// Check every possible quadruplet.
for (int i = 0; i < n - 3; i++) {
for (int j = i + 1; j < n - 2; j++) {
for (int k = j + 1; k < n - 1; k++) {
for (int l = k + 1; l < n; l++) {
if (arr[i] + arr[j] + arr[k] + arr[l] == x) {
return true;
}
}
}
}
}
return false;
}
public static void main(String[] args) {
int[] arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
System.out.println(fourSum(arr1, x1));
int[] arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
System.out.println(fourSum(arr2, x2));
}
}
def fourSum(arr, x):
n = len(arr)
# Check every possible quadruplet.
for i in range(n - 3):
for j in range(i + 1, n - 2):
for k in range(j + 1, n - 1):
for l in range(k + 1, n):
if arr[i] + arr[j] + arr[k] + arr[l] == x:
return True
return False
if __name__ == "__main__":
arr1 = [1, 5, 1, 0, 6, 0]
x1 = 7
print(str(fourSum(arr1, x1)).lower())
arr2 = [1, 2, 3, 4, 5]
x2 = 50
print(str(fourSum(arr2, x2)).lower())
using System;
class GFG {
static bool fourSum(int[] arr, int x) {
int n = arr.Length;
// Check every possible quadruplet.
for (int i = 0; i < n - 3; i++) {
for (int j = i + 1; j < n - 2; j++) {
for (int k = j + 1; k < n - 1; k++) {
for (int l = k + 1; l < n; l++) {
if (arr[i] + arr[j] + arr[k] + arr[l] == x) {
return true;
}
}
}
}
}
return false;
}
static void Main() {
int[] arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
Console.WriteLine(fourSum(arr1, x1).ToString().ToLower());
int[] arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
Console.WriteLine(fourSum(arr2, x2).ToString().ToLower());
}
}
'use strict';
/**
* @param {number[]} arr
* @param {number} x
* @returns {boolean}
*/
function fourSum(arr, x) {
const n = arr.length;
// Check every possible quadruplet.
for (let i = 0; i < n - 3; i++) {
for (let j = i + 1; j < n - 2; j++) {
for (let k = j + 1; k < n - 1; k++) {
for (let l = k + 1; l < n; l++) {
if (arr[i] + arr[j] + arr[k] + arr[l] === x) {
return true;
}
}
}
}
}
return false;
}
// Driver Code
const arr1 = [1, 5, 1, 0, 6, 0];
const x1 = 7;
console.log(fourSum(arr1, x1));
const arr2 = [1, 2, 3, 4, 5];
const x2 = 50;
console.log(fourSum(arr2, x2));
Output
true false
[Better Approach] Sorting and Two Pointers - O(n ^ 3) Time and O(1) Space
The idea is - First, sort the array. Fix the first two elements using two nested loops.
For the remaining two elements, use two pointers:
- Place left after the second fixed element.
- Place right at the end of the array.
- If the current sum is equal to x, return true.
- If the sum is smaller than x, increment left.
- Otherwise, decrement right.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
bool fourSum(vector<int>& arr, int x) {
int n = arr.size();
sort(arr.begin(), arr.end());
// Fix the first two elements.
for (int i = 0; i < n - 3; i++) {
for (int j = i + 1; j < n - 2; j++) {
int left = j + 1;
int right = n - 1;
// Find the remaining two elements using two pointers.
while (left < right) {
int sum = arr[i] + arr[j] + arr[left] + arr[right];
if (sum == x) {
return true;
}
if (sum < x) {
left++;
} else {
right--;
}
}
}
}
return false;
}
int main() {
vector<int> arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
cout << boolalpha << fourSum(arr1, x1) << endl;
vector<int> arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
cout << boolalpha << fourSum(arr2, x2) << endl;
return 0;
}
import java.util.Arrays;
class GFG {
static boolean fourSum(int[] arr, int x) {
int n = arr.length;
Arrays.sort(arr);
// Fix the first two elements.
for (int i = 0; i < n - 3; i++) {
for (int j = i + 1; j < n - 2; j++) {
int left = j + 1;
int right = n - 1;
// Find the remaining two elements using two pointers.
while (left < right) {
int sum = arr[i] + arr[j] + arr[left] + arr[right];
if (sum == x) {
return true;
}
if (sum < x) {
left++;
} else {
right--;
}
}
}
}
return false;
}
public static void main(String[] args) {
int[] arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
System.out.println(fourSum(arr1, x1));
int[] arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
System.out.println(fourSum(arr2, x2));
}
}
def fourSum(arr, x):
n = len(arr)
arr.sort()
# Fix the first two elements.
for i in range(n - 3):
for j in range(i + 1, n - 2):
left = j + 1
right = n - 1
# Find the remaining two elements using two pointers.
while left < right:
total = arr[i] + arr[j] + arr[left] + arr[right]
if total == x:
return True
if total < x:
left += 1
else:
right -= 1
return False
if __name__ == "__main__":
arr1 = [1, 5, 1, 0, 6, 0]
x1 = 7
print(str(fourSum(arr1, x1)).lower())
arr2 = [1, 2, 3, 4, 5]
x2 = 50
print(str(fourSum(arr2, x2)).lower())
using System;
class GFG {
static bool fourSum(int[] arr, int x) {
int n = arr.Length;
Array.Sort(arr);
// Fix the first two elements.
for (int i = 0; i < n - 3; i++) {
for (int j = i + 1; j < n - 2; j++) {
int left = j + 1;
int right = n - 1;
// Find the remaining two elements using two pointers.
while (left < right) {
int sum = arr[i] + arr[j] + arr[left] + arr[right];
if (sum == x) {
return true;
}
if (sum < x) {
left++;
} else {
right--;
}
}
}
}
return false;
}
static void Main() {
int[] arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
Console.WriteLine(fourSum(arr1, x1).ToString().ToLower());
int[] arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
Console.WriteLine(fourSum(arr2, x2).ToString().ToLower());
}
}
'use strict';
/**
* @param {number[]} arr
* @param {number} x
* @returns {boolean}
*/
function fourSum(arr, x) {
const n = arr.length;
arr.sort((a, b) => a - b);
// Fix the first two elements.
for (let i = 0; i < n - 3; i++) {
for (let j = i + 1; j < n - 2; j++) {
let left = j + 1;
let right = n - 1;
// Find the remaining two elements using two pointers.
while (left < right) {
const sum = arr[i] + arr[j] + arr[left] + arr[right];
if (sum === x) {
return true;
}
if (sum < x) {
left++;
} else {
right--;
}
}
}
}
return false;
}
// Driver Code
const arr1 = [1, 5, 1, 0, 6, 0];
const x1 = 7;
console.log(fourSum(arr1, x1));
const arr2 = [1, 2, 3, 4, 5];
const x2 = 50;
console.log(fourSum(arr2, x2));
Output
true false
[Expected Approach] Using Pair Sums - O(n ^ 2) Time and O(n ^ 2) Space
The idea is - Use a hash set to store the sums of pairs whose indices occur before the current pair.
For every pair (j, k), calculate: required = x - arr[j] - arr[k]
If required is already present in the set, a previous pair and the current pair together form four distinct elements whose sum is x.
After checking every pair beginning after index j, insert all pair sums (i, j), where i < j, into the set.
This insertion order ensures that the stored pair and the current pair do not share an index.
#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;
bool fourSum(vector<int>& arr, int x) {
int n = arr.size();
unordered_set<int> pairSums;
// Check pairs whose first index is j.
for (int j = 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
int required = x - arr[j] - arr[k];
if (pairSums.count(required)) {
return true;
}
}
// Store sums of pairs ending at index j.
for (int i = 0; i < j; i++) {
pairSums.insert(arr[i] + arr[j]);
}
}
return false;
}
int main() {
vector<int> arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
cout << boolalpha << fourSum(arr1, x1) << endl;
vector<int> arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
cout << boolalpha << fourSum(arr2, x2) << endl;
return 0;
}
import java.util.HashSet;
class GFG {
static boolean fourSum(int[] arr, int x) {
int n = arr.length;
HashSet<Integer> pairSums = new HashSet<>();
// Check pairs whose first index is j.
for (int j = 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
int required = x - arr[j] - arr[k];
if (pairSums.contains(required)) {
return true;
}
}
// Store sums of pairs ending at index j.
for (int i = 0; i < j; i++) {
pairSums.add(arr[i] + arr[j]);
}
}
return false;
}
public static void main(String[] args) {
int[] arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
System.out.println(fourSum(arr1, x1));
int[] arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
System.out.println(fourSum(arr2, x2));
}
}
def fourSum(arr, x):
n = len(arr)
pair_sums = set()
# Check pairs whose first index is j.
for j in range(1, n - 1):
for k in range(j + 1, n):
required = x - arr[j] - arr[k]
if required in pair_sums:
return True
# Store sums of pairs ending at index j.
for i in range(j):
pair_sums.add(arr[i] + arr[j])
return False
if __name__ == "__main__":
arr1 = [1, 5, 1, 0, 6, 0]
x1 = 7
print(str(fourSum(arr1, x1)).lower())
arr2 = [1, 2, 3, 4, 5]
x2 = 50
print(str(fourSum(arr2, x2)).lower())
using System;
using System.Collections.Generic;
class GFG {
static bool fourSum(int[] arr, int x) {
int n = arr.Length;
HashSet<int> pairSums = new HashSet<int>();
// Check pairs whose first index is j.
for (int j = 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
int required = x - arr[j] - arr[k];
if (pairSums.Contains(required)) {
return true;
}
}
// Store sums of pairs ending at index j.
for (int i = 0; i < j; i++) {
pairSums.Add(arr[i] + arr[j]);
}
}
return false;
}
static void Main() {
int[] arr1 = {1, 5, 1, 0, 6, 0};
int x1 = 7;
Console.WriteLine(fourSum(arr1, x1).ToString().ToLower());
int[] arr2 = {1, 2, 3, 4, 5};
int x2 = 50;
Console.WriteLine(fourSum(arr2, x2).ToString().ToLower());
}
}
'use strict';
/**
* @param {number[]} arr
* @param {number} x
* @returns {boolean}
*/
function fourSum(arr, x) {
const n = arr.length;
const pairSums = new Set();
// Check pairs whose first index is j.
for (let j = 1; j < n - 1; j++) {
for (let k = j + 1; k < n; k++) {
const required = x - arr[j] - arr[k];
if (pairSums.has(required)) {
return true;
}
}
// Store sums of pairs ending at index j.
for (let i = 0; i < j; i++) {
pairSums.add(arr[i] + arr[j]);
}
}
return false;
}
// Driver Code
const arr1 = [1, 5, 1, 0, 6, 0];
const x1 = 7;
console.log(fourSum(arr1, x1));
const arr2 = [1, 2, 3, 4, 5];
const x2 = 50;
console.log(fourSum(arr2, x2));
Output
true false