Open In App

Unique Numbers ||

Last Updated : 21 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] containing 2*n + 2 positive numbers, out of which 2*n numbers exist in pairs whereas the other two number occur exactly once and are distinct. The task is to find the other two numbers.

Note: Return the numbers in increasing order.

Example:

Input: arr[] = [1, 2, 3, 2, 1, 4]
Output: 3 4
Explanation: 3 and 4 occur exactly once.

Input: arr[] = [2, 1, 3, 2]
Output: 1 3
Explanation: 1 and 3 occur exactly once.

[Naive Approach] Nested Loop Frequency Counting – O(n^2) Time and O(1) Space

This approach iterates through the array and counts the frequency of each element using a nested loop. For each element, the inner loop counts how many times it appears in the array. If an element appears exactly once, it is returned as the result. This method ensures that the correct element is identified but is inefficient due to the nested loop, finally return them in sorted order.

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


vector<int> singleNum(vector<int>& arr) {
    int n = arr.size();
    
    vector<int> ans;
    // Iterate over every element
    for (int i = 0; i < n; i++) {

        // Initialize count to 0
        int count = 0;

        for (int j = 0; j < n; j++) {

            // Count the frequency of the element
            if (arr[i] == arr[j]) {
                count++;
            }
        }

        // If the frequency of the element is one
        if (count == 1) {
            ans.push_back(arr[i]);
        }
    }
    
    sort(ans.begin(), ans.end());
    // If no element exists at most once
    return ans;
}

int main() {
    vector<int> arr = { 1, 2, 3, 2, 1, 4 };
    vector<int> ans = singleNum(arr);
    for(auto it:ans)
        cout<<it<<" ";
    return 0;
}
Java
import java.util.*;

class GfG {

    static int[] singleNum(int[] arr) {
        

        // Collect elements that appear exactly once
        List<Integer> result = new ArrayList<>();
        for(int i=0;i<arr.length;i++){
            int count = 0;
            for(int j=0;j<arr.length;j++){
                
                // count the frequency of element arr[i]
                if(arr[i]==arr[j])
                    count++;
            }
            if(count == 1)result.add(arr[i]);
        }

        // Sort the result list
        Collections.sort(result);

        // Convert List<Integer> to int[]
        int[] resArray = new int[result.size()];
        for (int i = 0; i < result.size(); i++) {
            resArray[i] = result.get(i);
        }

        return resArray;
    }

    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 2, 1, 4 };
        int[] result = singleNum(arr);

        // Print the result array
        for(int i=0;i<result.length;i++){
            System.out.print(result[i] + " ");
        }
    }
}
Python
def singleNum(arr):
    n = len(arr)
    result = []

    # Iterate over every element
    for i in range(n):
        count = 0

        for j in range(n):
            if arr[i] == arr[j]:
                count += 1

        # If the frequency of the element is one and not already in result
        if count == 1:
            result.append(arr[i])

    # Return sorted result
    return sorted(result)

if __name__ == "__main__":
    arr = [1, 2, 3, 2, 1, 4]
    print(*singleNum(arr))
C#
using System;
using System.Collections.Generic;

class GfG {

    static List<int> singleNum(int[] arr) {
        int n = arr.Length;
        List<int> result = new List<int>();

        for (int i = 0; i < n; i++) {
            int count = 0;

            for (int j = 0; j < n; j++) {
                if (arr[i] == arr[j]) {
                    count++;
                }
            }

            // If the frequency is one and not already in the result list
            if (count == 1 && !result.Contains(arr[i])) {
                result.Add(arr[i]);
            }
        }

        // Sort the result before returning
        result.Sort();
        return result;
    }

    static void Main(string[] args) {
        int[] arr = { 1, 2, 3, 2, 1, 4 };
        List<int> singles = singleNum(arr);

        foreach (int num in singles) {
            Console.Write(num + " ");
        }
    }
}
JavaScript
function singleNum(arr) {
    let n = arr.length;
    let result = [];

    for (let i = 0; i < n; i++) {
        let count = 0;

        for (let j = 0; j < n; j++) {
            if (arr[i] === arr[j]) {
                count++;
            }
        }

        // If the frequency is one and not already added
        if (count === 1 && !result.includes(arr[i])) {
            result.push(arr[i]);
        }
    }

    // Sort the result in ascending order
    result.sort((a, b) => a - b);
    return result;
}


// dirver code
let arr = [1, 2, 3, 2, 1, 4];
let ans = singleNum(arr); 
console.log(ans.join(" "));

Output
3 4 

[Better Approach 1] Using Sorting – O(n logn) time and O(1) space

This approach first sorts the array to group identical elements next to each other. Then, it iterates through the sorted array, checking for pairs of identical elements and skipping them. If an element is unique (appears only once), it is added to the result. This method ensures that the two unique elements are found and returned efficiently after sorting.

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> singleNum(vector<int> &arr) {
    int n = arr.size();

    sort(arr.begin(), arr.end());

    vector<int> ans;
    int i = 0;
    
    while (i < n) {
        
        // If element is present twice, skip
        if (i + 1 < n && arr[i + 1] == arr[i]) {
            i = i + 2;
        }
        
        // If unique, append to result
        else {
            ans.push_back(arr[i]);
            i++;
        }
    }

    return ans;
}

int main() {
    vector<int> arr = { 1, 2, 3, 2, 1, 4 };
    vector<int> ans = singleNum(arr);
    cout << ans[0] << " " << ans[1] << endl;
    return 0;
}
Java
import java.util.Arrays;

public class GfG {

    public static int[] singleNum(int[] arr) {
        Arrays.sort(arr);
        int n = arr.length;
        // Temporary array to store unique elements
        int[] temp = new int[n]; 
        int idx = 0;
        int i = 0;

        while (i < n) {
            // If element is present twice, skip both
            if (i + 1 < n && arr[i + 1] == arr[i]) {
                i += 2;
            } else {
                // If unique, store in temp
                temp[idx++] = arr[i];
                i++;
            }
        }

        // Copy valid elements to a properly-sized array
        int[] result = new int[idx];
        for (int j = 0; j < idx; j++) {
            result[j] = temp[j];
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 2, 1, 4 };
        int[] ans = singleNum(arr);

        // Print the result array
        for (int i = 0; i < ans.length; i++) {
            System.out.print(ans[i] + " ");
        }
    }
}
Python
def singleNum(arr):
    arr.sort()
    ans = []
    i = 0
    n = len(arr)

    while i < n:
        # If element is present twice, skip
        if i + 1 < n and arr[i + 1] == arr[i]:
            i += 2
        else:
            # If unique, append to result
            ans.append(arr[i])
            i += 1

    return ans

if __name__ == '__main__':
    arr = [1, 2, 3, 2, 1, 4]
    ans = singleNum(arr)
    print(ans[0], ans[1])
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GfG {
    static List<int> SingleNum(List<int> arr) {
        arr.Sort();
        List<int> ans = new List<int>();
        int i = 0;

        while (i < arr.Count) {
            
            // If element is present twice, skip
            if (i + 1 < arr.Count && arr[i + 1] == arr[i]) {
                i += 2;
            }
            // If unique, append to result
            else {
                ans.Add(arr[i]);
                i++;
            }
        }

        return ans;
    }

    static void Main() {
        List<int> arr = new List<int> { 1, 2, 3, 2, 1, 4 };
        List<int> ans = SingleNum(arr);
        Console.WriteLine(ans[0] + " " + ans[1]);
    }
}
JavaScript
function singleNum(arr) {
    arr.sort((a, b) => a - b);
    let ans = [];
    let i = 0;

    while (i < arr.length) {
        // If element is present twice, skip
        if (i + 1 < arr.length && arr[i + 1] === arr[i]) {
            i += 2;
        }
        // If unique, append to result
        else {
            ans.push(arr[i]);
            i++;
        }
    }

    return ans;
}

const arr = [1, 2, 3, 2, 1, 4];
const ans = singleNum(arr);
console.log(ans[0] + ' ' + ans[1]);

Output
3 4

[Better Approach 2] Using HashMap – O(n) time and O(n) space

This approach uses an unordered map (freq) to track the frequency of elements in the array. After building the frequency map, it collects elements that occur exactly once and returns them in ascending order.

C++
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> singleNum(const vector<int>& arr) {
    unordered_map<int, int> freq;
    
    // Count the frequency of each element
    for (int x : arr) {
        freq[x]++;
    }
    
    vector<int> res;
    
    // Collect numbers that appear exactly once
    for (const auto& p : freq) {
        if (p.second == 1) {
            res.push_back(p.first);
        }
    }
    
    if (res[0] > res[1]) {
        swap(res[0], res[1]);
    }    
    return res;
}

int main() {
    vector<int> arr = {1, 2, 3, 2, 1, 4};
    
    vector<int> res = singleNum(arr);
    
    for (int x : res) {
        cout << x << " ";
    }
    cout << endl;

    return 0;
}
Java
import java.util.*;

public class GfG {
    public static int[] singleNum(int[] arr) {
        Map<Integer, Integer> freq = new HashMap<>();

        // Count the frequency of each element
        for (int x : arr) {
            freq.put(x, freq.getOrDefault(x, 0) + 1);
        }

        List<Integer> temp = new ArrayList<>();

        // Collect numbers that appear exactly once
        for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
            if (entry.getValue() == 1) {
                temp.add(entry.getKey());
            }
        }

        // Sort the result
        Collections.sort(temp);

        // Convert to int[]
        int[] result = new int[temp.size()];
        for (int i = 0; i < temp.size(); i++) {
            result[i] = temp.get(i);
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 2, 1, 4};
        int[] res = singleNum(arr);

        for (int x : res) {
            System.out.print(x + " ");
        }
        System.out.println();
    }
}
Python
def singleNum(arr):
    freq = {}
    
    # Count the frequency of each element
    for x in arr:
        freq[x] = freq.get(x, 0) + 1
    
    res = []
    
    # Collect numbers that appear exactly once
    for key, value in freq.items():
        if value == 1:
            res.append(key)
    
    if res[0] > res[1]:
        res[0], res[1] = res[1], res[0]
    return res

if __name__ == '__main__':
    arr = [1, 2, 3, 2, 1, 4]
    res = singleNum(arr)
    
    for x in res:
        print(x, end=' ')
    print()
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GfG {
    public static List<int> SingleNum(int[] arr) {
        Dictionary<int, int> freq = new Dictionary<int, int>();
        
        // Count the frequency of each element
        foreach (int x in arr) {
            if (freq.ContainsKey(x)) {
                freq[x]++;
            } else {
                freq[x] = 1;
            }
        }
        
        List<int> res = new List<int>();
        
        // Collect numbers that appear exactly once
        foreach (var p in freq) {
            if (p.Value == 1) {
                res.Add(p.Key);
            }
        }
        
        if (res[0] > res[1]) {
            int temp = res[0];
            res[0] = res[1];
            res[1] = temp;
        }
        return res;
    }

    static void Main() {
        int[] arr = {1, 2, 3, 2, 1, 4};
        List<int> res = SingleNum(arr);
        
        foreach (int x in res) {
            Console.Write(x + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
function singleNum(arr) {
    const freq = {};
    
    // Count the frequency of each element
    for (let x of arr) {
        freq[x] = (freq[x] || 0) + 1;
    }
    
    const res = [];
    
    // Collect numbers that appear exactly once
    for (const key in freq) {
        if (freq[key] === 1) {
            res.push(Number(key));
        }
    }
    
    if (res[0] > res[1]) {
        [res[0], res[1]] = [res[1], res[0]];
    }
    return res;
}

const arr = [1, 2, 3, 2, 1, 4];
const res = singleNum(arr);
console.log(res.join(" "));

Output
3 4 

[Expected Approach] Using Bit Manipulation – O(n) time and O(1) space

The key idea is that by XOR-ing all elements in the array, we eliminate the effect of all numbers that appear twice (since a ^ a = 0), leaving us with x ^ y, the XOR of the two unique elements. We then find any set bit (typically the rightmost set bit) in this result to determine a position where these two numbers differ. Using this bit, we split the numbers into two groups, XOR each group separately, and get the two unique numbers.

To find the rightmost set bit in xorVal, we use the expression xorVal & (-xorVal). This is a common bit manipulation trick that isolates the lowest (rightmost) bit that is set to 1. It works because in two’s complement, -xorVal is the bitwise inverse of xorVal plus one, which flips all bits after the rightmost 1, thus leaving only that 1 bit in the AND operation. This bit tells us a position where the two numbers (say, x and y) differ , one has a 1 at this position, and the other has a 0.

This trick is particularly efficient and often used in problems involving two unique elements among duplicates. However, if we don’t specifically need the rightmost set bit, we can alternatively find any set bit by scanning bit positions, or using other logical operations

Illustration:

Given the array [2, 4, 7, 9, 2, 4], XOR all elements to get 14. The rightmost set bit of 14 is at position 1. Divide the array into two groups based on this bit:

  • Group 1 (bit set at position 1): [2, 7, 2]
  • Group 2 (bit not set): [4, 9, 4]

XOR the elements in each group:

  • Group 1: 2 ^ 7 ^ 2 = 7
  • Group 2: 4 ^ 9 ^ 4 = 9

The two non-repeating elements are 7 and 9.

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> singleNum(vector<int> &arr) {
    
    // Get the XOR of the two numbers we need to find
    int xorVal = 0;
    for (auto i : arr) {
        xorVal = i ^ xorVal;
    }

    // Get its last set bit
    xorVal &= -xorVal;

    vector<int> res(2, 0);
    
    for (int num : arr) {
        // If bit is not set, it belongs to the first set
        if ((num & xorVal) == 0) { 
            res[0] ^= num;
        }
        
        // If bit is set, it belongs to the second set
        else { 
            res[1] ^= num;
        }
    }

    // Ensure the order of the returned numbers is consistent
    if (res[0] > res[1]) {
        swap(res[0], res[1]);
    }

    return res;
}

int main() {
    vector<int> arr = { 1, 2, 3, 2, 1, 4 };
    vector<int> ans = singleNum(arr);
    cout << ans[0] << " " << ans[1] << endl;
    return 0;
}
Java
import java.util.Arrays;
import java.util.List;

public class GfG {
    public static int[] singleNum(int[] arr) {
        
        // Get the XOR of the two numbers we need to find
        int xorVal = 0;
        for (int i : arr) {
            xorVal ^= i;
        }

        // Get its last set bit
        xorVal &= -xorVal;

        int[] res = new int[2];
        
        for (int num : arr) {
            
            // If bit is not set, it belongs to the first set
            if ((num & xorVal) == 0) { 
                res[0] ^= num;
            }
            
            // If bit is set, it belongs to the second set
            else { 
                res[1] ^= num;
            }
        }

        // Ensure the order of the returned numbers is consistent
        if (res[0] > res[1]) {
            int temp = res[0];
            res[0] = res[1];
            res[1] = temp;
        }

        return res;
    }

    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 2, 1, 4 };
        int[] ans = singleNum(arr);
        System.out.println(ans[0] + " " + ans[1]);
    }
}
Python
def singleNum(arr):
    
    # Get the XOR of the two numbers we need to find
    xor_val = 0
    for i in arr:
        xor_val ^= i

    # Get its last set bit
    xor_val &= -xor_val

    res = [0, 0]
    
    for num in arr:
        
        # If bit is not set, it belongs to the first set
        if (num & xor_val) == 0:
            res[0] ^= num
            
        # If bit is set, it belongs to the second set
        else:
            res[1] ^= num

    # Ensure the order of the returned numbers is consistent
    if res[0] > res[1]:
        res[0], res[1] = res[1], res[0]

    return res

# Main execution
arr = [1, 2, 3, 2, 1, 4]
ans = singleNum(arr)
print(ans[0], ans[1])
C#
using System;
using System.Collections.Generic;

class Solution {
    public int[] SingleNum(int[] arr) {
        
        // Get the XOR of the two numbers we need to find
        int xorVal = 0;
        foreach (int i in arr) {
            xorVal ^= i;
        }

        // Get its last set bit
        xorVal &= -xorVal;

        int[] res = new int[2];

        foreach (int num in arr) {
            
            // If bit is not set, it belongs to the first set
            if ((num & xorVal) == 0) {
                res[0] ^= num;
            }
            
            // If bit is set, it belongs to the second set
            else {
                res[1] ^= num;
            }
        }

        // Ensure the order of the returned numbers is consistent
        if (res[0] > res[1]) {
            int temp = res[0];
            res[0] = res[1];
            res[1] = temp;
        }

        return res;
    }

    static void Main() {
        int[] arr = { 1, 2, 3, 2, 1, 4 };
        Solution sol = new Solution();
        int[] ans = sol.SingleNum(arr);
        Console.WriteLine(ans[0] + " " + ans[1]);
    }
}
JavaScript
function singleNum(arr) {
    
    // Get the XOR of the two numbers we need to find
    let xorVal = 0;
    for (let i of arr) {
        xorVal ^= i;
    }

    // Get its last set bit
    xorVal &= -xorVal;

    let res = [0, 0];

    for (let num of arr) {
        
        // If bit is not set, it belongs to the first set
        if ((num & xorVal) === 0) {
            res[0] ^= num;
        }
        
        // If bit is set, it belongs to the second set
        else {
            res[1] ^= num;
        }
    }

    // Ensure the order of the returned numbers is consistent
    if (res[0] > res[1]) {
        [res[0], res[1]] = [res[1], res[0]];
    }

    return res;
}

const arr = [1, 2, 3, 2, 1, 4];
const ans = singleNum(arr);
console.log(ans[0] + ' ' + ans[1]);

Output
3 4

Please refer below post for detailed explanation: 



Next Article

Similar Reads