Given an integer array nums.Return all triplets such that:
Notice that the solution set must not contain duplicate triplets. One element can be a part of multiple triplets. The output and the triplets can be returned in any order.
Input: nums = [2, -2, 0, 3, -3, 5]
Output: [[-2, 0, 2], [-3, -2, 5], [-3, 0, 3]]
Explanation: nums[1] + nums[2] + nums[0] = 0
nums[4] + nums[1] + nums[5] = 0
nums[4] + nums[2] + nums[3] = 0
Input: nums = [2, -1, -1, 3, -1]
Output: [[-1, -1, 2]]
Explanation: nums[1] + nums[2] + nums[0] = 0
Note that we have used two -1s as they are separate elements with different indexes
But we have not used the -1 at index 4 as that would create a duplicate triplet
Input: nums = [8, -6, 5, 4]
(Give answer with the output and triplets sorted in ascending order)
The most naive idea is to check all possible triplets using 3 loops and among them, consider the ones whose sum is equal to the given target 0. 
Before taking them as the answer, sort the triplets in ascending order so as to consider only the unique triplets.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    //Function to find triplets having sum equals to target
    vector<vector<int>> threeSum(vector<int>& nums) {
        // Set to store unique triplets
        set<vector<int>> tripletSet;
        int n = nums.size();
        // Check all possible triplets
        for (int i = 0; i < n - 2; i++) {
            for (int j = i + 1; j < n - 1; j++) {
                for (int k = j + 1; k < n; k++) {
                    if (nums[i] + nums[j] + nums[k] == 0) {
                        // Found a triplet that sums up to target
                        vector<int> temp = {nums[i], nums[j], nums[k]};
                        
                        /* Sort the triplet to ensure
                         uniqueness when storing in set*/
                        sort(temp.begin(), temp.end());
                        tripletSet.insert(temp);
                        
                    }
                }
            }
        }
        // Convert set to vector (unique triplets)
        vector<vector<int>> ans(tripletSet.begin(), tripletSet.end());
       //Return the ans
        return ans;
    }
};
int main() {
    vector<int> nums = {-1, 0, 1, 2, -1, -4};
    // Create an instance of Solution class
    Solution sol;
    vector<vector<int>> ans = sol.threeSum(nums);
    // Print the result
    for (auto& triplet : ans) {
        cout << "[";
        for (auto& num : triplet) {
            cout << num << " ";
        }
        cout << "] ";
    }
    cout << "\n";
    return 0;
}
import java.util.*;
class Solution {
    //Function to find triplets having sum equals to target
    public List<List<Integer>> threeSum(int[] nums) {
        // Set to store unique triplets
        Set<List<Integer>> tripletSet = new HashSet<>();
        int n = nums.length;
        // Check all possible triplets
        for (int i = 0; i < n - 2; i++) {
            for (int j = i + 1; j < n - 1; j++) {
                for (int k = j + 1; k < n; k++) {
                    if (nums[i] + nums[j] + nums[k] == 0) {
                        // Found a triplet that sums up to target
                        List<Integer> temp = new ArrayList<>();
                        temp.add(nums[i]);
                        temp.add(nums[j]);
                        temp.add(nums[k]);
                        
                        /* Sort the triplet to ensure 
                        uniqueness when storing in set*/
                        Collections.sort(temp);
                        tripletSet.add(temp);
                    }
                }
            }
        }
        // Convert set to list of lists (unique triplets)
        List<List<Integer>> ans = new ArrayList<>(tripletSet);
        //Return the ans
        return ans;
    }
}
public class Main {
    public static void main(String[] args) {
        int[] nums = {-1, 0, 1, 2, -1, -4};
        // Create an instance of Solution class
        Solution sol = new Solution();
        List<List<Integer>> ans = sol.threeSum(nums);
        // Print the result
        for (List<Integer> triplet : ans) {
            System.out.print("[");
            for (int num : triplet) {
                System.out.print(num + " ");
            }
            System.out.print("] ");
        }
        System.out.println();
    }
}
from typing import List
class Solution:
    #Function to find triplets having sum equals to target
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # Set to store unique triplets
        triplet_set = set()
        n = len(nums)
        # Check all possible triplets
        for i in range(n - 2):
            for j in range(i + 1, n - 1):
                for k in range(j + 1, n):
                    if nums[i] + nums[j] + nums[k] == 0:
                        # Found a triplet that sums up to target
                        temp = [nums[i], nums[j], nums[k]]
                        
                        """ Sort the triplet to ensure 
                        uniqueness when storing in set"""
                        temp.sort()
                        triplet_set.add(tuple(temp))
        
        # Convert set to list of lists (unique triplets)
        ans = [list(triplet) for triplet in triplet_set]
        #Return the ans
        return ans
if __name__ == "__main__":
    nums = [-1, 0, 1, 2, -1, -4]
    # Create an instance of Solution class
    sol = Solution()
    ans = sol.threeSum(nums)
    # Print the result
    for triplet in ans:
        print(f"[{', '.join(map(str, triplet))}]")
class Solution {
    // Function to find triplets having sum equals to target
    threeSum(nums) {
        // Set to store unique triplets
        let tripletSet = new Set();
        let n = nums.length;
        // Check all possible triplets
        for (let i = 0; i < n - 2; i++) {
            for (let j = i + 1; j < n - 1; j++) {
                for (let k = j + 1; k < n; k++) {
                    if (nums[i] + nums[j] + nums[k] === 0) {
                        // Found a triplet that sums up to target
                        let temp = [nums[i], nums[j], nums[k]];
                        
                        /* Sort the triplet to ensure
                        uniqueness when storing in set*/
                        temp.sort((a, b) => a - b);
                        tripletSet.add(temp.join(','));
                    }
                }
            }
        }
        // Convert set to array of arrays (unique triplets)
        let ans = Array.from(tripletSet).map(triplet => triplet.split(',').map(num => parseInt(num)));
        // Return the ans
        return ans;
    }
}
// Main function to test the solution
let nums = [-1, 0, 1, 2, -1, -4];
// Create an instance of Solution class
let sol = new Solution();
let ans = sol.threeSum(nums);
// Print the result
ans.forEach(triplet => {
    console.log(`[${triplet.join(', ')}]`);
});
The better approach uses simple mathematics where some calculative parameter is taken in RHS(right hand side) to compute the result. 
For example if a + b  + c = 0, then a + b = -c. Similar idea is used here. 
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    // Function to find triplets having sum equals to target
    vector<vector<int>> threeSum(vector<int>& nums) {
        // Set to store unique triplets
        set<vector<int>> tripletSet;
        int n = nums.size();
        // Check all possible triplets
        for (int i = 0; i < n; i++) {
            // Set to store elements seen so far in the loop
            set<int> hashset;
            for (int j = i + 1; j < n; j++) {
                // Calculate the 3rd element needed to reach target
                int third = - (nums[i] + nums[j]);
                /* Find if third element exists in
                hashset (complements seen so far)*/
                if (hashset.find(third) != hashset.end()) {
                    // Found a triplet that sums up to target
                    vector<int> temp = {nums[i], nums[j], third};
                    
                    /* Sort the triplet to ensure 
                    uniqueness when storing in set*/
                    sort(temp.begin(), temp.end());
                    tripletSet.insert(temp);
                }
                
                /* Insert the current element
                into hashset for future checks*/
                hashset.insert(nums[j]);
            }
        }
        // Convert set to vector (unique triplets)
        vector<vector<int>> ans(tripletSet.begin(), tripletSet.end());
        //Return the ans
        return ans;
    }
};
int main() {
    vector<int> nums = {-1, 0, 1, 2, -1, -4};
    // Create an instance of Solution class
    Solution sol;
    vector<vector<int>> ans = sol.threeSum(nums);
    // Print the result
    for (auto& triplet : ans) {
        cout << "[";
        for (auto& num : triplet) {
            cout << num << " ";
        }
        cout << "] ";
    }
    cout << "\n";
    return 0;
}
import java.util.*;
class Solution {
    // Function to find triplets having sum equals to 0
    public List<List<Integer>> threeSum(int[] nums) {
        // Set to store unique triplets
        Set<List<Integer>> tripletSet = new HashSet<>();
        int n = nums.length;
        // Check all possible triplets
        for (int i = 0; i < n; i++) {
            // Set to store elements seen so far in the loop
            Set<Integer> hashset = new HashSet<>();
            for (int j = i + 1; j < n; j++) {
                // Calculate the 3rd element needed to reach 0
                int third =  - (nums[i] + nums[j]);
                /* Find if third element exists in
                hashset (complements seen so far)*/
                if (hashset.contains(third)) {
                    // Found a triplet that sums up to target
                    List<Integer> temp = new ArrayList<>();
                    temp.add(nums[i]);
                    temp.add(nums[j]);
                    temp.add(third);
                    /* Sort the triplet to ensure
                    uniqueness when storing in set*/
                    Collections.sort(temp);
                    tripletSet.add(temp);
                }
                /* Insert the current element 
                 into hashset for future checks*/
                hashset.add(nums[j]);
            }
        }
        // Convert set to list of lists (unique triplets)
        List<List<Integer>> ans = new ArrayList<>(tripletSet);
        //Return the ans
        return ans;
    }
    public static void main(String[] args) {
        int[] nums = {-1, 0, 1, 2, -1, -4};
        // Create an instance of Solution class
        Solution sol = new Solution();
        List<List<Integer>> ans = sol.threeSum(nums);
        // Print the result
        for (List<Integer> triplet : ans) {
            System.out.print("[");
            for (int num : triplet) {
                System.out.print(num + " ");
            }
            System.out.print("] ");
        }
        System.out.println();
    }
}
from typing import List
class Solution:
    # Function to find triplets having sum equals to 0
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # Set to store unique triplets
        triplet_set = set()
        n = len(nums)
        # Check all possible triplets
        for i in range(n):
            # Set to store elements seen so far in the loop
            hashset = set()
            for j in range(i + 1, n):
                # Calculate the 3rd element needed to reach target
                third =  - (nums[i] + nums[j])
                """ Find if third element exists in
                 hashset (complements seen so far)"""
                if third in hashset:
                    # Found a triplet that sums up to target
                    temp = [nums[i], nums[j], third]
                    """ Sort the triplet to ensure
                    uniqueness when storing in set"""
                    temp.sort()
                    triplet_set.add(tuple(temp))
                """ Insert the current element 
                into hashset for future checks"""
                hashset.add(nums[j])
        # Convert set to list of lists (unique triplets)
        ans = [list(triplet) for triplet in triplet_set]
        #Return the ans
        return ans
if __name__ == "__main__":
    nums = [-1, 0, 1, 2, -1, -4]
    # Create an instance of Solution class
    sol = Solution()
    ans = sol.threeSum(nums)
    # Print the result
    for triplet in ans:
        print(f"[{', '.join(map(str, triplet))}]")
class Solution {
    // Function to find triplets having sum equals to 0
    threeSum(nums) {
        // Set to store unique triplets
        let tripletSet = new Set();
        let n = nums.length;
        // Check all possible triplets
        for (let i = 0; i < n; i++) {
            // Set to store elements seen so far in the loop
            let hashset = new Set();
            for (let j = i + 1; j < n; j++) {
                // Calculate the 3rd element needed to reach target
                let third =  - (nums[i] + nums[j]);
                /* Find if third element exists in 
                hashset (complements seen so far)*/
                if (hashset.has(third)) {
                    // Found a triplet that sums up to target
                    let temp = [nums[i], nums[j], third];
                    /* Sort the triplet to ensure 
                    uniqueness when storing in set*/
                    temp.sort((a, b) => a - b);
                    tripletSet.add(JSON.stringify(temp));
                }
                /* Insert the current element
                into hashset for future checks*/
                hashset.add(nums[j]);
            }
        }
        // Convert set to list of lists (unique triplets)
        let ans = Array.from(tripletSet).map(triplet => JSON.parse(triplet));
        //Return the ans
        return ans;
    }
}
// Main function to test the solution
let nums = [-1, 0, 1, 2, -1, -4];
// Create an instance of Solution class
let sol = new Solution();
let ans = sol.threeSum(nums);
// Print the result
ans.forEach(triplet => {
    console.log(`[${triplet.join(', ')}]`);
});
Imagine you're organizing a dinner party and you want to create a balanced meal with three different ingredients that together have zero net calories.
First task would be to list all your ingredients by their calorie values and sort them. Then, for each ingredient, try to find two other ingredients from the remaining list that, when combined, balance the calories back to zero.
Start with one ingredient and use two pointers, one starting from the left (beginning of the list) and the other from the right (end of the list). By adjusting these pointers, check if the three chosen ingredients balance to zero calories. If they do, you have a balanced meal! Continue this process, ensuring that the same combination of ingredients more than once is not picked.












#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    // Function to find triplets having sum equals to target
    vector<vector<int>> threeSum(vector<int>& nums) {
        
        // Vector to store the triplets that sum up to target
        vector<vector<int>> ans;
        
        int n = nums.size();
        
        // Sort the input array nums
        sort(nums.begin(), nums.end());
        
        // Iterate through the array to find triplets
        for (int i = 0; i < n; i++) {
            // Skip duplicates
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            
            // Two pointers approach
            int j = i + 1;
            int k = n - 1;
            
            while (j < k) {
                int sum = nums[i] + nums[j] + nums[k];
                
                if (sum < 0) {
                    j++;
                } else if (sum > 0) {
                    k--;
                } else {
                    // Found a triplet that sums up to target
                    vector<int> temp = {nums[i], nums[j], nums[k]};
                    ans.push_back(temp);
                    
                    // Skip duplicates
                    j++;
                    k--;
                    while (j < k && nums[j] == nums[j - 1]) j++;
                    while (j < k && nums[k] == nums[k + 1]) k--;
                }
            }
        }
        
        return ans;
    }
};
int main() {
    vector<int> nums = {-1, 0, 1, 2, -1, -4};
    
    // Create an instance of Solution class
    Solution sol;
    
    vector<vector<int>> ans = sol.threeSum(nums);
    
    // Print the result
    for (auto& triplet : ans) {
        cout << "[";
        for (auto& num : triplet) {
            cout << num << " ";
        }
        cout << "] ";
    }
    cout << "\n";
    
    return 0;
}
import java.util.*;
class Solution {
    // Function to find triplets having sum equals to target
    public List<List<Integer>> threeSum(int[] nums) {
        
        // List to store the triplets that sum up to target
        List<List<Integer>> ans = new ArrayList<>();
        
        int n = nums.length;
        
        // Sort the input array nums
        Arrays.sort(nums);
        
        // Iterate through the array to find triplets
        for (int i = 0; i < n; i++) {
            // Skip duplicates
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            
            // Two pointers approach
            int j = i + 1;
            int k = n - 1;
            
            while (j < k) {
                int sum = nums[i] + nums[j] + nums[k];
                
                if (sum < 0) {
                    j++;
                } else if (sum > 0) {
                    k--;
                } else {
                    // Found a triplet that sums up to target
                    List<Integer> temp = new ArrayList<>();
                    temp.add(nums[i]);
                    temp.add(nums[j]);
                    temp.add(nums[k]);
                    ans.add(temp);
                    
                    // Skip duplicates
                    j++;
                    k--;
                    while (j < k && nums[j] == nums[j - 1]) j++;
                    while (j < k && nums[k] == nums[k + 1]) k--;
                }
            }
        }
        
        return ans;
    }
}
public class Main {
    public static void main(String[] args) {
        int[] nums = {-1, 0, 1, 2, -1, -4};
        
        // Create an instance of Solution class
        Solution sol = new Solution();
        
        List<List<Integer>> ans = sol.threeSum(nums);
        
        // Print the result
        for (List<Integer> triplet : ans) {
            System.out.print("[");
            for (int num : triplet) {
                System.out.print(num + " ");
            }
            System.out.print("] ");
        }
        System.out.println();
    }
}
from typing import List
class Solution:
    # Function to find triplets having sum equals to target
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        
        # List to store the triplets that sum up to target
        ans = []
        
        n = len(nums)
        
        # Sort the input array nums
        nums.sort()
        
        # Iterate through the array to find triplets
        for i in range(n):
            # Skip duplicates
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            
            # Two pointers approach
            j = i + 1
            k = n - 1
            
            while j < k:
                sum_val = nums[i] + nums[j] + nums[k]
                
                if sum_val < 0:
                    j += 1
                elif sum_val > 0:
                    k -= 1
                else:
                    # Found a triplet that sums up to target
                    temp = [nums[i], nums[j], nums[k]]
                    ans.append(temp)
                    
                    # Skip duplicates
                    j += 1
                    k -= 1
                    while j < k and nums[j] == nums[j - 1]:
                        j += 1
                    while j < k and nums[k] == nums[k + 1]:
                        k -= 1
        
        return ans
if __name__ == "__main__":
    nums = [-1, 0, 1, 2, -1, -4]
    
    # Create an instance of Solution class
    sol = Solution()
    ans = sol.threeSum(nums)
    
    # Print the result
    for triplet in ans:
        print(f"[{', '.join(map(str, triplet))}]")
class Solution {
    // Function to find triplets having sum equals to target
    threeSum(nums) {
        
        // Array to store the triplets that sum up to target
        let ans = [];
        
        // Sort the input array nums
        nums.sort((a, b) => a - b);
        
        let n = nums.length;
        
        // Iterate through the array to find triplets
        for (let i = 0; i < n; i++) {
            // Skip duplicates
            if (i > 0 && nums[i] === nums[i - 1]) continue;
            
            // Two pointers approach
            let j = i + 1;
            let k = n - 1;
            
            while (j < k) {
                let sumVal = nums[i] + nums[j] + nums[k];
                
                if (sumVal < 0) {
                    j++;
                } else if (sumVal > 0) {
                    k--;
                } else {
                    // Found a triplet that sums up to target
                    let temp = [nums[i], nums[j], nums[k]];
                    ans.push(temp);
                    
                    // Skip duplicates
                    j++;
                    k--;
                    while (j < k && nums[j] === nums[j - 1]) j++;
                    while (j < k && nums[k] === nums[k + 1]) k--;
                }
            }
        }
        
        return ans;
    }
}
// Main function to test the Solution class
function main() {
    let nums = [-1, 0, 1, 2, -1, -4];
    
    // Create an instance of Solution class
    let sol = new Solution();
    let ans = sol.threeSum(nums);
    
    // Print the result
    ans.forEach(triplet => {
        console.log(`[${triplet.join(', ')}]`);
    });
}
// Invoke the main function
main();
Q: How do we avoid duplicate triplets?
A: Skip duplicate values of nums[i] while iterating. Skip duplicate values of nums[left] and nums[right] during the two-pointer traversal.
Q: Why sort the array?
A: Sorting allows: Efficient identification of duplicates by comparing adjacent elements. Simplification of the two-pointer logic, as the relationship between pointer movements and the sum becomes predictable.
Q: What if the input array is unsorted?
A: Sorting is part of the solution and is necessary for efficient implementation. It adds O(nlogn) complexity, which is negligible compared to the O(n2) time required for finding triplets.
Q: How would you modify the algorithm to find all unique triplets with a sum equal to a different target?
A: Instead of finding triplets that sum to 0: Look for triplets that sum to a given target t. Use the same two-pointer approach, with nums[left]+nums[right]=t−nums[i].