CLOSE
🛠️ Settings

Problem Statement

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that:

  • i, j, and k are distinct indices.
  • nums[i] + nums[j] + nums[k] == 0.

Note:

  • The solution set must not contain duplicate triplets.
  • The output can be returned in any order.

LeetCode:

Examples

Example 1:

Input: nums = [-1, 0, 1, 2, -1, -4]
Output: [ [-1, 0, 1], [-1, -1, 2] ]

Explanation:
nums[0] + nums[1] + nums[2] = 0
-1 + 0 + 1 = 0

nums[0] + nums[5] + nums[4] = 0
-1 + -1 + 2 = 0
Example 2:

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
Example 3:

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
Example 4:

Input: nums = [0, 1, 1]
Output: []

Explanation:
No triplets sum to zero.

Problem Understanding:

The Three Sum Zero problem requires finding all unique triplets in an array whose sum is zero.

Example Explanation:

In the given example, the array [-1, 0, 1, 2, -1, -4] has two unique triplets that add up to zero. [-1, 0, 1] and [-1, -1, 2]. These triplets are the subsets of the array whose elements, when summed, result in zero.

Different Approaches to Solve:

1️⃣ Brute Force:

A brute-force approach involves using three nested loops to check every triplet in the array. This approach has a time complexity of O(n^3) and is not the most efficient for large arrays.

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.

Approach

  1. Declare a set data structure for storing the unique triplets.
  2. Used nested looping structure to traverse the array, and take triplets into account.
  3. First loop will run from 0th index till the length of array, lets call it i. Inside it, there will be the another loop(say j) that will run from i+1 to n-1. Then a third loop(say k) that runs from j+1 to n-1.
  4. Now, inside these 3 nested loops, check the sum of arr[i] and arr[j] and arr[k], and if it is equal to the target i.e. 0 sort this triplet and insert it in the set data structure. Finally, return the list of triplets stored in the set data structure.

Dry Run:

initialization:

       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^     ^
          |     |     |
          i     j     k

      +--------------+
set = |     empty    |
      +--------------+
i = 0, j = 1, k = 2
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^     ^
          |     |     |
          i     j     k

      +--------------+
set = |     empty    |
      +--------------+
      
if (arr[i] + arr[j] + arr[k] == 0)
     arr[0] + arr[1] + arr[2] == 0
     -1 + 0 + 1 == 0
     True
          Create a temp vector of i, j, k which would
              be [-1, 0, 1]
          Sort temp vector, { why? without sorting
                             the trplets [-1, 0, 1] and
                             [0, -1, 1] would be
                             treated as different
                             triplets, even though they
                             contain the same elements.
                             By sorting the triplet,
                             both [-1, 0, 1] and
                             [0, -1, 1] become
                             [-1, 0, 1] and thus
                             recognized as the same
                             triplet.
                             }
          Insert the temp vector into the set.
          k++
i = 0, j = 1, k = 2
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^           ^
          |     |           |
          i     j           k

      +--------------+
set = |  [-1, 0, 1]  |
      +--------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[1] + arr[3] == 0
     -1 + 0 + 2 == 0
     False
     
     k++
i = 0, j = 1, k = 4
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^                 ^
          |     |                 |
          i     j                 k

      +--------------+
set = |  [-1, 0, 1]  |
      +--------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[1] + arr[4] == 0
     -1 + 0 + 1 == 0
     True
          Create a temp vector of i, j, k which would
              be [-1, 0, 1]
          Sort temp vector
          
          Insert the temp vector into the set {since
          this triplet already present in the set, it
          won't be inserted.}
     
     k++
i = 0, k = 1, j = 5
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^                       ^
          |     |                       |
          i     j                       k

      +--------------+
set = |  [-1, 0, 1]  |
      +--------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[1] + arr[4] == 0
     -1 + 0 + -4 == 0
     False
     
     Since incrementing k, would go out of the arrays
     bounds so, terminate this most inside loop and 
     increment j, and reset k to j + 1.
i = 0, j = 2, k = 3
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^           ^     ^
          |           |     |
          i           j     k

      +--------------+
set = |  [-1, 0, 1]  |
      +--------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[2] + arr[3] == 0
     -1 + 1 + 2 == 0
     False
     
     k++
i = 0, k = 2, j = 4
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^           ^           ^
          |           |           |
          i           j           k

      +--------------+
set = |  [-1, 0, 1]  |
      +--------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[2] + arr[4] == 0
     -1 + 1 + -1 == 0
     False
     
     k++
i = 0, j = 2, k = 5
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^           ^                 ^
          |           |                 |
          i           j                 k

      +--------------+
set = |  [-1, 0, 1]  |
      +--------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[2] + arr[5] == 0
     -1 + 1 + -4 == 0
     False
     
     Since incrementing k, would go out of the arrays
     bounds so, terminate this most inside loop and 
     increment j, and reset k to j + 1.
i = 0, j = 3, k =4
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^                 ^     ^
          |                 |     |
          i                 j     k

      +--------------+
set = |  [-1, 0, 1]  |
      +--------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[3] + arr[4] == 0
     -1 + 2 + -1 == 0
     True
          Create a temp vector of i, j, k which would
              be [-1, 2, -1]
          Sort temp vector, { why? without sorting
                            the trplets [-1, 2, -1] and
                             [-1, -1, 2] would be
                             treated as different
                             triplets, even though they
                             contain the same elements.
                             By sorting the triplet,
                             both [-1, 2, -1] and
                             [-1, -1, 2] become
                             [-1, -1, 2] and thus
                             recognized as the same
                             triplet.
                             }
          Insert the temp vector into the set.
          k++
i = 0, j = 3, k = 5
       +-----+-----+-----+-----+-----+-----+
nums = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^                 ^           ^
          |                 |           |
          i                 j           k

      +--------------+---------------+
set = |  [-1, 0, 1]  |  [-1, -1, 2]  |
      +--------------+---------------+

if (arr[i] + arr[j] + arr[k] == 0)
    arr[0] + arr[3] + arr[5] == 0
     -1 + 2 + -4 == 0
     False
     
     Since incrementing k, would go out of the arrays
     bounds so, terminate this most inside loop and 
     increment j, and reset k to j + 1.
Continue
Keep doing this process
For i = 0 to n-3
    For j = i + 1 to n-2
        For k = j + 1 to n-1

Code:

#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());
        
        // OR
        /*
        for(auto itr: tripletSet) {
            ans.push_back(itr);
        }
        */

       //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;
}

Complexity Analysis:

  • Time Complexity: O(N^3 x log(no. of unique triplets)), where N is size of the array. Using 3 nested loops & inserting triplets into the set takes O(log(no. of unique triplets)) time complexity. But we are not considering the time complexity of sorting as we are just sorting 3 elements every time.
  • Space Complexity: O(2 x no. of the unique triplets) for using a set data structure and a list to store the triplets.

2️⃣ Better Approach

Intuition:

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.

Approach:

  1. Declare a set data structure to store unique triplets. Then iterate in the array lets call the variable i from index 0 to n -1. Inside it, there will be the second loop(say j) that will run from i+1 to n-1.
  2. Declare another HashSet to store the array elements as we intend to search for the third element using this HashSet.
  3. Inside the nested loop, calculate the value of the third element i.e. -(arr[i]+arr[j]).
  4. If the third element exists in the HashSet, sort these 3 values i.e. arr[i], arr[j], and the third element, and insert it in the set data structure declared in step 1.
  5. After that, insert the j-th element i.e. arr[j] in the HashSet as we only want to insert those array elements that are in between indices i and j. Finally, return a list of triplets stored in the set data structure.

Dry Run:

Initialization
       +-----+-----+-----+-----+-----+-----+
 arr = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^
          |     |
          i     j

             +--------------+
Result set = |     empty    |
             +--------------+

i = 0, j = 1
       +-----+-----+-----+-----+-----+-----+
 arr = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^
          |     |
          i     j

             +--------------+
Result set = |     empty    |
             +--------------+

              +--------------+
tempHashSet = |     empty    |
              +--------------+
              
     third = - (arr[i] + arr[j])
     third = - (-1 + 0)
     third = 1
          Does hashSet contains third which is 1.
          False
          Add 1 to hashSet
          j++
i = 0, j = 1
       +-----+-----+-----+-----+-----+-----+
 arr = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^           ^
          |           |
          i           j

             +--------------+
Result set = |     empty    |
             +--------------+

              +-----+
tempHashSet = |  1  |
              +-----+
              
     third = - (arr[i] + arr[j])
     third = - (-1 + 1)
     third = 0
          Does hashSet contains third which is 0.
          False
          Add 0 to hashSet
          j++
i = 0, j = 2
       +-----+-----+-----+-----+-----+-----+
 arr = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^                 ^
          |                 |
          i                 j

             +--------------+
Result set = |     empty    |
             +--------------+

              +-----+-----+
tempHashSet = |  1  |  0  |
              +-----+-----+
              
     third = - (arr[i] + arr[j])
     third = - (-1 + 2)
     third = 1
          Does hashSet contains third which is 1.
          True
               Create temp vector {arr[i], arr[j], third}
               Sort the temp vector
               Insert the vector into the resultSet
          j++
i = 0, j = 3
       +-----+-----+-----+-----+-----+-----+
 arr = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^                       ^
          |                       |
          i                       j

             +--------------+
Result set = | (-1, 1, 2)   |
             +--------------+

              +-----+-----+
tempHashSet = |  1  |  0  |
              +-----+-----+
              
     third = - (arr[i] + arr[j])
     third = - (-1 + (-1))
     third = - (-1 - 1)
     third = - (-2)
     third = 2
          Does hashSet contains third which is 2.
          False
          Add 2 to hashSet
          j++
Continue
Keep doing this process
For i = 0 to n-1
    For j = i + 1 to n

Code:

#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;
}

3️⃣ Optimal Approach

Sorting + Two-Pointers:

Sort the array and use two pointers to find pairs that sum to the negative of the current element. This approach reduces the time complexity to O(n^2) due to sorting step.

Approach:

  1. Sort the entire array & iterate from 0 to n-1 in the array, lets call the loop variable i. In each iteration, this value will be fixed for all different values of the rest of the 2 pointers.
  2. Inside the loop, first check if the current and the previous element is the same and if it is, do nothing and continue to the next value of i.
  3. After that, there will be 2 moving pointers i.e. j(starts from i+1) and k(starts from the last index). The pointer j will move forward and the pointer k will move backward until they cross each other while the value of i will be fixed.
  4. Now check the sum of arr[i] and arr[j] and arr[k]. If the sum is exceeding target, then the ask is to use lesser valued elements and so decrease the value of k(i.e. k--). If the sum is lesser than the target, we need a bigger value and so increase the value of j (i.e. j++).
  5. If the sum is equal to the target, simply insert the triplet i.e. arr[i], arr[j], arr[k] into answer data structure and move the pointers j and k skipping the duplicate elements(i.e. by checking the adjacent elements while moving the pointers). Finally, return the list of unique triplets.

Dry Run:

Initialization
       +-----+-----+-----+-----+-----+-----+
 arr = | -1  |  0  |  1  |  2  | -1  | -4  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          
 Sort the arr

       +-----+-----+-----+-----+-----+-----+
 arr = | -4  | -1  | -1  |  0  |  1  |  2  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          
Initialize the Loop
       +-----+-----+-----+-----+-----+-----+
 arr = | -4  | -1  | -1  |  0  |  1  |  2  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^                       ^
          |     |                       |
          i     j                       k
          
             +--------------+
Result set = |              |
             +--------------+
i = 0, j = 1, k = 5
       +-----+-----+-----+-----+-----+-----+
 arr = | -4  | -1  | -1  |  0  |  1  |  2  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^     ^                       ^
          |     |                       |
          i     j                       k

i = 0
j = 1
k = 5

             +--------------+
Result set = |              |
             +--------------+

sum = arr[i] + arr[j] + arr[k]
    = -4 + (-1) + 2
    = -4 - 1 + 2
    = -5 + 2
    = -3
    Since sum is less than 0 increment the left pointer which is j.
      Keep incrementing until arr[j] != arr[j - 1] && j < k
    j++
i = 0, j = 3, k = 5
       +-----+-----+-----+-----+-----+-----+
 arr = | -4  | -1  | -1  |  0  |  1  |  2  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^                 ^           ^
          |                 |           |
          i                 j           k

i = 0
j = 3
k = 5

             +--------------+
Result set = |              |
             +--------------+

sum = arr[i] + arr[j] + arr[k]
    = -4 + 0 + 2
    = -4 + 2
    = -2
    Since sum is less than 0 increment the left pointer which is j.
      Keep incrementing until arr[j] != arr[j - 1] && j < k
    j++
i = 0, j = 4, k = 5
       +-----+-----+-----+-----+-----+-----+
 arr = | -4  | -1  | -1  |  0  |  1  |  2  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
          ^                       ^     ^
          |                       |     |
          i                       j     k

i = 0
j = 4
k = 5

             +--------------+
Result set = |              |
             +--------------+

sum = arr[i] + arr[j] + arr[k]
    = -4 + 1 + 2
    = -4 + 3
    = -1
    Since sum is less than 0 increment the left pointer which is j.
      Keep incrementing until arr[j] != arr[j - 1] && j < k
      Now since j will become equal to k so break the internal loop.
      and reset j, k to (i + 1) and (size() - 1) respectively.
i = 1, j = 2, k = 5
       +-----+-----+-----+-----+-----+-----+
 arr = | -4  | -1  | -1  |  0  |  1  |  2  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
                ^     ^                 ^
                |     |                 |
                i     j                 k

i = 1
j = 2
k = 5

             +--------------+
Result set = |              |
             +--------------+


sum = arr[i] + arr[j] + arr[k]
    = -1 - 1 + 2
    = 0
    Push this combination into the result vector.
    Increment j and decrement k.
    Skip duplication by checking nums[j] != nums[j - 1]
                                 nums[k] != nums[k + 1]
Keep Doing until i < nums.size()
        +-----+-----+-----+-----+-----+-----+
 arr = | -4  | -1  | -1  |  0  |  1  |  2  |
       +-----+-----+-----+-----+-----+-----+
          0     1     2     3     4     5
                ^     ^           ^
                |     |           |
                i     j           k

i = 1
j = 2
k = 5

             +--------------+
Result set = |              |
             +--------------+


sum = arr[i] + arr[j] + arr[k]
    = -1 - 1 + 2
    = 0
    Push this combination into the result vector.
    Increment j and decrement k.
    Skip duplication by checking nums[j] != nums[j - 1]
                                 nums[k] != nums[k + 1]
three-sum-1.jpg
three-sum-2.jpg
three-sum-3.jpg

Code:

#include <iostream>
#include <vector>
#include <algorithm>

// Function to find all unique triplets that sum to zero using sorting and two pointers
std::vector<std::vector<int>> threeSumSorting(std::vector<int>& nums) {
    std::vector<std::vector<int>> result;  // Vector to store the triplets
    int n = nums.size();

    // Step 1: Sort the array to facilitate two-pointer approach and to handle duplicates
    std::sort(nums.begin(), nums.end());

    // Step 2: Traverse through each element, considering it as the first element of the triplet
    for (int i = 0; i < n - 2; ++i) {
        // Skip duplicate elements to avoid repeated triplets
        if (i > 0 && nums[i] == nums[i - 1])
            continue;

        int left = i + 1;     // Pointer to the next element
        int right = n - 1;    // Pointer to the last element

        // Step 3: Use two pointers to find the other two elements of the triplet
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];  // Calculate the sum of the triplet

            if (sum == 0) {  // If the sum is zero, we've found a valid triplet
                result.push_back({nums[i], nums[left], nums[right]});  // Store the triplet
                
                // Move the left pointer to the right, skipping duplicates
                while (left < right && nums[left] == nums[left + 1])
                    ++left;
                
                // Move the right pointer to the left, skipping duplicates
                while (left < right && nums[right] == nums[right - 1])
                    --right;
                
                // Move both pointers to continue finding other triplets
                ++left;
                --right;
            } else if (sum < 0) {  // If the sum is less than zero, move the left pointer to increase the sum
                ++left;
            } else {  // If the sum is greater than zero, move the right pointer to decrease the sum
                --right;
            }
        }
    }

    return result;  // Return the result containing all the valid triplets
}

int main() {
    std::vector<int> nums = {-1, 0, 1, 2, -1, -4};  // Input array
    std::vector<std::vector<int>> result = threeSumSorting(nums);  // Call the function

    // Print the result
    std::cout << "Triplets with Zero Sum (Sorting + Two Pointers):\n";
    for (const auto& triplet : result) {  // Iterate through each triplet
        std::cout << "[";
        for (int num : triplet) {  // Print the numbers in each triplet
            std::cout << num << " ";
        }
        std::cout << "]\n";
    }

    return 0;
}

Complexity Analysis:

  • Time Complexity: O(n log n) + O(n^2), where n is the size of the array.
    • As the pointer i, is running for approximately N times. And both the pointers j and k combined can run for approximately N times including the operation of skipping duplicates. So the total time complexity will be O(N^2).
  • Space Complexity: O(1), no extra space is needed.