Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to find all the unique quadruplets that is close to zero using C#?
Finding all unique quadruplets that sum to zero in C# is a classic algorithmic problem known as the 4Sum problem. The goal is to find all combinations of four distinct elements from an array whose sum equals zero, avoiding duplicate quadruplets.
Problem Approaches
There are multiple approaches to solve this problem, each with different time and space complexities −
| Approach | Time Complexity | Space Complexity | Description |
|---|---|---|---|
| Brute Force | O(n4) | O(1) | Four nested loops checking all combinations |
| HashSet Optimization | O(n3) | O(n) | Use HashSet to find fourth element |
| Two Pointers | O(n3) | O(1) | Sort array and use two pointers technique |
Using Two Pointers Approach
The most efficient approach involves sorting the array first, then using two nested loops for the first two elements and two pointers for the remaining two elements −
using System;
using System.Collections.Generic;
using System.Linq;
public class FourSumSolution {
public List<List<int>> FourSum(int[] nums, int target = 0) {
List<List<int>> result = new List<List<int>>();
if (nums == null || nums.Length < 4) {
return result;
}
Array.Sort(nums);
for (int i = 0; i < nums.Length - 3; i++) {
// Skip duplicates for first element
if (i > 0 && nums[i] == nums[i - 1]) continue;
for (int j = i + 1; j < nums.Length - 2; j++) {
// Skip duplicates for second element
if (j > i + 1 && nums[j] == nums[j - 1]) continue;
int left = j + 1;
int right = nums.Length - 1;
while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
result.Add(new List<int> { nums[i], nums[j], nums[left], nums[right] });
// Skip duplicates for third and fourth elements
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
else if (sum < target) {
left++;
}
else {
right--;
}
}
}
}
return result;
}
}
class Program {
public static void Main(string[] args) {
FourSumSolution solution = new FourSumSolution();
int[] nums = { 1, 0, -1, 0, -2, 2 };
var quadruplets = solution.FourSum(nums);
Console.WriteLine("Unique quadruplets that sum to zero:");
foreach (var quadruplet in quadruplets) {
Console.WriteLine("[" + string.Join(", ", quadruplet) + "]");
}
}
}
The output of the above code is −
Unique quadruplets that sum to zero: [-2, -1, 1, 2] [-2, 0, 0, 2] [-1, 0, 0, 1]
Using HashSet for Different Target
Here's an alternative approach using HashSet that allows for different target sums −
using System;
using System.Collections.Generic;
using System.Linq;
public class HashSetApproach {
public List<List<int>> FourSumWithHashSet(int[] nums, int target = 0) {
List<List<int>> result = new List<List<int>>();
HashSet<string> seen = new HashSet<string>();
if (nums == null || nums.Length < 4) return result;
for (int i = 0; i < nums.Length - 3; i++) {
for (int j = i + 1; j < nums.Length - 2; j++) {
HashSet<int> set = new HashSet<int>();
for (int k = j + 1; k < nums.Length; k++) {
int complement = target - nums[i] - nums[j] - nums[k];
if (set.Contains(complement)) {
var quadruplet = new List<int> { nums[i], nums[j], nums[k], complement };
quadruplet.Sort();
string key = string.Join(",", quadruplet);
if (!seen.Contains(key)) {
seen.Add(key);
result.Add(quadruplet);
}
}
set.Add(nums[k]);
}
}
}
return result;
}
}
class Program {
public static void Main(string[] args) {
HashSetApproach solution = new HashSetApproach();
int[] nums = { 2, 1, -2, -1, 0, 3 };
var quadruplets = solution.FourSumWithHashSet(nums, 0);
Console.WriteLine("Quadruplets using HashSet approach:");
foreach (var quadruplet in quadruplets) {
Console.WriteLine("[" + string.Join(", ", quadruplet) + "]");
}
}
}
The output of the above code is −
Quadruplets using HashSet approach: [-2, -1, 1, 2] [-2, 0, 1, 1] [-1, 0, 0, 1]
How It Works
The two-pointer approach works by first sorting the array, then fixing the first two elements with nested loops. For each pair, it uses two pointers (left and right) to find the remaining two elements that complete the target sum. Duplicate handling is crucial to ensure unique quadruplets.
The algorithm systematically moves the pointers based on whether the current sum is greater than, less than, or equal to the target, efficiently exploring all possible combinations without redundancy.
Conclusion
The 4Sum problem can be efficiently solved using the two-pointer technique with O(n³) time complexity. The key is proper duplicate handling and systematic exploration of all valid quadruplets that sum to the target value.
