Unique Number III (original) (raw)

Given an array where every element occurs three times, except one element which occurs only once. Find the element that occurs once.

**Examples:

**Input: arr[] = [1, 10, 1, 1]
**Output: 10
**Explanation: 10 occurs once in the array while the other element 1 occurs thrice.

**Input: arr[] = [3, 2, 1, 34, 34, 1, 2, 34, 2, 1]
**Output: 3
**Explanation: All elements except 3 occurs thrice in the array.

Table of Content

[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.

C++ `

#include #include using namespace std;

int getSingle(vector& arr) { int n = arr.size();

// 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) {
        return arr[i];
    }
}

// If no element exists at most once
return -1;

}

int main() { vector arr = {1, 10, 1, 1}; cout << getSingle(arr) << endl; return 0; }

Java

import java.util.*;

class GfG {

static int getSingle(int[] arr) {
    int n = arr.length;

    // 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) {
            return arr[i];
        }
    }

    // If no element exists at most once
    return -1;
}

public static void main(String[] args) {
    int[] arr = {1, 10, 1, 1};
    System.out.println(getSingle(arr));
}

}

Python

def getSingle(arr): n = len(arr)

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

    # Initialize count to 0
    count = 0

    for j in range(n):

        # Count the frequency of the element
        if arr[i] == arr[j]:
            count += 1

    # If the frequency of the element is one
    if count == 1:
        return arr[i]

# If no element exists at most once
return -1

if name == "main": arr = [1, 10, 1, 1] print(getSingle(arr))

C#

using System;

class GfG {

static int getSingle(int[] arr) {
    int n = arr.Length;

    // 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) {
            return arr[i];
        }
    }

    // If no element exists at most once
    return -1;
}

static void Main(string[] args) {
    int[] arr = {1, 10, 1, 1};
    Console.WriteLine(getSingle(arr));
}

}

JavaScript

function getSingle(arr) { let n = arr.length;

// Iterate over every element
for (let i = 0; i < n; i++) {

    // Initialize count to 0
    let count = 0;

    for (let 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) {
        return arr[i];
    }
}

// If no element exists at most once
return -1;

}

let arr = [1, 10, 1, 1]; console.log(getSingle(arr));

`

[Better Approach 1] Count Frequency of Elements Using Map - O(n) Time and O(n) Space

Use a map or dictionary to count the frequency of each element in the array. Then, iterate through the map and return the element whose frequency is exactly one.

C++ `

#include #include #include using namespace std;

// Function to find the element that appears only once int getSingle(vector& arr) {

// To store frequency of each element
unordered_map<int, int> freq;  

// Count the frequency of each number in the array
for (int num : arr) {
    freq[num]++;
}

// Find the number that occurs only once
for (auto it : freq) {
    if (it.second == 1)
        return it.first;
}

// Return 0 if no unique element is found
return 0;

}

int main() { vector arr = {1, 10, 1, 1};

// Output the single occurrence element
cout << getSingle(arr) << endl;

return 0;

}

Java

import java.util.ArrayList; import java.util.HashMap;

public class GfG{

// Function to find the element that appears only once
public static int getSingle(int [] arr) {
    HashMap<Integer, Integer> mp = new HashMap<>();

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

    // Return the element that appears only once
    for (var it : mp.entrySet()) {
        if (it.getValue() == 1) {
            return it.getKey();
        }
    }

    return 0;
}

public static void main(String[] args) {
    int [] arr = {1, 10, 1, 1};

    System.out.println(getSingle(arr));
}

}

Python

def getSingle(arr): mp = {}

# Count frequency of each element
for it in arr:
    if it in mp:
        mp[it] += 1
    else:
        mp[it] = 1

# Return the element that appears only once
for key in mp:
    if mp[key] == 1:
        return key

return 0

if name == "main": arr = [1, 10, 1, 1] print(getSingle(arr))

C#

using System; using System.Collections.Generic;

class GfG { // Function to find the element that appears only once public static int getSingle(int [] arr) { Dictionary<int, int> mp = new Dictionary<int, int>();

    // Count frequency of each element
    foreach (int it in arr)
    {
        if (mp.ContainsKey(it))
            mp[it]++;
        else
            mp[it] = 1;
    }

    // Return the element that appears only once
    foreach (var it in mp)
    {
        if (it.Value == 1)
            return it.Key;
    }

    return 0;
}

public static void Main()
{
    int [] arr = { 1, 10, 1, 1 };

    Console.WriteLine(getSingle(arr));
}

}

JavaScript

function getSingle(arr) { const mp = new Map();

// Count frequency of each element
for (const it of arr) {
    mp.set(it, (mp.get(it) || 0) + 1);
}

// Return the element that appears only once
for (const [key, value] of mp.entries()) {
    if (value === 1) {
        return key;
    }
}

return 0;

}

// Example usage const arr = [1, 10, 1, 1]; console.log(getSingle(arr));

`

[Better Approach 2] Using Math - O(n) Time and O(n) Space

This approach works by leveraging a clever mathematical trick involving the sum of all elements and the sum of unique elements. In the given problem, every element appears exactly three times except one, which appears only once. By summing all elements in the array (totalSum ) and also summing only the unique elements using a set (uniqueSum), we notice that if all elements appeared three times, then 3 * uniqueSum would equal totalSum. However, since one element appears only once, the difference 3 * uniqueSum - totalSum equals twice the unique element. Dividing this result by 2 gives us the value of the single-occurring element.

This method is efficient and avoids complex logic, working perfectly under the assumption that all other elements appear exactly three times.

C++ `

#include #include #include using namespace std;

int getSingle(vector& arr) { unordered_set uniqueElements; int totalSum = 0;

// Calculate the sum of all elements and collect unique ones
for (int num : arr) {
    totalSum += num;
    uniqueElements.insert(num);
}

int uniqueSum = 0;

// Sum of all unique elements
for (int num : uniqueElements) {
    uniqueSum += num;
}

//  3 * (sum of unique elements) - (sum of all elements)
//  gives twice the unique element that appears once.
//  So we divide by 2 to get the actual element.
int result = (3 * uniqueSum - totalSum) / 2;
return result;

}

int main() { vector arr = {1, 10, 1, 1};

// Output the single occurrence element
cout << getSingle(arr) << endl;

return 0;

}

Java

import java.util.HashSet;

public class Main {

public static int getSingle(int[] arr) {
    HashSet<Integer> uniqueElements = new HashSet<>();
    int totalSum = 0;

    // Calculate the sum of all elements and collect unique ones
    for (int num : arr) {
        totalSum += num;
        uniqueElements.add(num);
    }

    int uniqueSum = 0;

    // Sum of all unique elements
    for (int num : uniqueElements) {
        uniqueSum += num;
    }

    // 3 * (sum of unique elements) - (sum of all elements) = 2 * unique one
    return (3 * uniqueSum - totalSum) / 2;
}

public static void main(String[] args) {
    int[] arr = {1, 10, 1, 1};

    // Output the single occurrence element
    System.out.println(getSingle(arr));
}

}

Python

def getSingle(arr): unique_elements = set() total_sum = 0

# Calculate total sum and collect unique elements
for num in arr:
    total_sum += num
    unique_elements.add(num)

unique_sum = sum(unique_elements)

# 3 * (sum of unique elements) - (sum of all elements) = 2 * unique one
result = (3 * unique_sum - total_sum) // 2
return result

Driver code

if name == "main": arr = [1, 10, 1, 1] print(getSingle(arr))

C#

using System; using System.Collections.Generic;

class Program { public static int GetSingle(int[] arr) { HashSet uniqueElements = new HashSet(); int totalSum = 0;

    // Calculate total sum and collect unique elements
    foreach (int num in arr)
    {
        totalSum += num;
        uniqueElements.Add(num);
    }

    int uniqueSum = 0;

    // Sum of all unique elements
    foreach (int num in uniqueElements)
    {
        uniqueSum += num;
    }

    // 3 * (sum of unique elements) - (sum of all elements) = 2 * unique one
    return (3 * uniqueSum - totalSum) / 2;
}

static void Main()
{
    int[] arr = { 1, 10, 1, 1 };

    // Output the single occurrence element
    Console.WriteLine(GetSingle(arr));
}

}

JavaScript

function getSingle(arr) { const uniqueElements = new Set(); let totalSum = 0;

// Calculate total sum and collect unique elements
for (let num of arr) {
    totalSum += num;
    uniqueElements.add(num);
}

let uniqueSum = 0;
for (let num of uniqueElements) {
    uniqueSum += num;
}

// 3 * (sum of unique elements) - (sum of all elements) = 2 * unique one
return (3 * uniqueSum - totalSum) / 2;

}

// Driver code let arr = [1, 10, 1, 1]; console.log(getSingle(arr));

`

**[Expected Approach 1] Using Bit Manipulation - O(n) Time and O(1) Space

The approach is based on the observation that in a binary representation of numbers, the bits that are set to 1 in the number that occurs only once will have a sum that is not a multiple of 3, while the bits that are set to 1 in the numbers that occur three times will have a sum that is a multiple of 3.

Here's a breakdown of the intuition:

**Note: this approach won't work for negative numbers

C++ `

#include #include using namespace std;

int getSingle(vector& arr) { int result = 0, x, sum;

// Iterate through every bit (from 0 to 31)
for (int i = 0; i < 32; i++) {
    sum = 0;
    
     // Get the mask for the i-th bit position
    x = (1 << i); 

    // Iterate over the array and count the number of set
    // bits at position i
    for (int j = 0; j < arr.size(); j++) {
        
        // Check if the i-th bit is set in arr[j]
        if (arr[j] & x) {  
            sum++;
        }
    }

    // If sum is not a multiple of 3, it's part of the unique element
    if ((sum % 3) != 0) {
        result |= x;
    }
}

return result;  

}

int main() { vector arr = {1, 10, 1, 1}; cout << getSingle(arr) << endl; return 0; }

Java

public class GfG { public static int getSingle(int[] arr) { int result = 0, x, sum;

    // Iterate through every bit (from 0 to 31)
    for (int i = 0; i < 32; i++) {
        sum = 0;
        x = (1 << i);  // Mask for the i-th bit

        // Count how many numbers have the i-th bit set
        for (int j = 0; j < arr.length; j++) {
            if ((arr[j] & x) != 0) {
                sum++;
            }
        }

        // If sum is not a multiple of 3, that bit belongs
        // to the unique number
        if ((sum % 3) != 0) {
            result |= x;
        }
    }

    return result;
}

public static void main(String[] args) {
    int[] arr = {1, 10, 1, 1};

    System.out.println(getSingle(arr));  
}

}

Python

def getSingle(arr): result = 0

# Iterate through every bit (from 0 to 31)
for i in range(32):
    sum = 0
    
    # Get the mask for the i-th bit position
    x = (1 << i)

    # Iterate over the array and count the number of set bits 
    # at position i
    for j in arr:
        # Check if the i-th bit is set in j
        if j & x:
            sum += 1

    # If sum is not a multiple of 3, it's part of the unique element
    if sum % 3 != 0:
        result |= x

return result

arr = [1, 10, 1, 1] print(getSingle(arr))

C#

using System; using System.Collections.Generic;

class GfG { static int getSingle(int [] arr) { int result = 0, x, sum;

    // Iterate through every bit (from 0 to 31)
    for (int i = 0; i < 32; i++) {
        sum = 0;
        
        // Get the mask for the i-th bit position
        x = (1 << i);

        // Iterate over the array and count the number of set bits 
        // at position i
        foreach (int j in arr) {
            
            // Check if the i-th bit is set in j
            if ((j & x) != 0) {
                sum++;
            }
        }

        // If sum is not a multiple of 3, it's part of the unique element
        if (sum % 3 != 0) {
            result |= x;
        }
    }

    return result;
}

static void Main() {
    int [] arr =  { 1, 10, 1, 1 };
    Console.WriteLine(getSingle(arr));
}

}

JavaScript

function getSingle(arr) { let result = 0;

// Iterate through every bit (from 0 to 31)
for (let i = 0; i < 32; i++) {
    let sum = 0;
    
    // Get the mask for the i-th bit position
    let x = (1 << i);

    // Iterate over the array and count the number of set 
    // bits at position i
    for (let j = 0; j < arr.length; j++) {
        // Check if the i-th bit is set in arr[j]
        if (arr[j] & x) {
            sum++;
        }
    }

    // If sum is not a multiple of 3, it's part of the unique element
    if (sum % 3 !== 0) {
        result |= x;
    }
}

return result;

}

const arr = [1, 10, 1, 1]; console.log(getSingle(arr));

`

**[Expected Approach 2] Using Bitmask - O(n) Time and O(1) Space

Use two variables, ones and twos, to track the bits that appear an odd and even number of times, respectively. In each iteration, XOR the current element with ones to update ones with the bits that occur an odd number of times. Then, use a bitwise AND between ones and the current element to identify the common bits that appear exactly three times. These common bits are then removed from both ones and twos using a bitwise AND with the negation of the common bits. After all iterations, ones will hold the element that appears only once.

**Step by step Implementation:

#include #include using namespace std;

int getSingle(vector& arr) { int ones = 0, twos = 0, mask;

for (int num : arr) {
    
    // Update 'twos' with bits that are set in both 'ones' and 
    // current number. These are bits that have appeared twice so far.
    twos |= ones & num;  
    
    // XOR current number with 'ones' to add bits appearing
    // odd number of times.If a bit has appeared once, it is set
    // if it's the second time, it gets unset.
    ones ^= num;         

    
    // (ones & twos) gives bits that are set in both, meaning they 
    // have now appeared 3 times. ~(ones & twos) inverts it to create 
    // a mask where those bits are 0 (to be cleared), and others are 1.
    // Applying this mask on 'ones' and 'twos' removes the 
    // bits that have appeared three times.
    mask = ~(ones & twos);  

    // Apply mask to keep only valid bits that haven't appeared 3 times.
    ones &= mask;
    twos &= mask;
}


return ones;  

}

int main() { vector arr = {1, 10, 1, 1}; cout << getSingle(arr) << endl; return 0; }

Java

import java.util.List; import java.util.ArrayList;

class GfG { public static int getSingle(int [] arr) { int ones = 0, twos = 0, mask;

    for (int num : arr) {
        
        
        // Update 'twos' with bits that are set in both 'ones' and 
        // current number. These are bits that have appeared twice so far.
        twos |= ones & num;
        
        // XOR current number with 'ones' to add bits appearing
        // odd number of times.If a bit has appeared once, it is set
        // if it's the second time, it gets unset.
        ones ^= num;
        
       // (ones & twos) gives bits that are set in both, meaning they 
       // have now appeared 3 times. ~(ones & twos) inverts it to create 
       // a mask where those bits are 0 (to be cleared), and others are 1.
       // Applying this mask on 'ones' and 'twos' removes the 
       // bits that have appeared three times.
        mask = ~(ones & twos);
        ones &= mask;
        twos &= mask;
    }

    return ones;
}

public static void main(String[] args) {
    int [] arr = {1, 10, 1, 1};
    System.out.println(getSingle(arr));
}

}

Python

def getSingle(arr): ones, twos = 0, 0

for num in arr:

    # Update 'twos' with bits that are set in both 'ones' and 
    # current number. These are bits that have appeared twice so far.
    twos |= ones & num
    
    # XOR current number with 'ones' to add bits appearing
    # odd number of times.If a bit has appeared once, it is set
    # if it's the second time, it gets unset.
    ones ^= num
    
    # (ones & twos) gives bits that are set in both, meaning they 
    # have now appeared 3 times. ~(ones & twos) inverts it to create 
    # a mask where those bits are 0 (to be cleared), and others are 1.
    # Applying this mask on 'ones' and 'twos' removes the 
    # bits that have appeared three times.
    mask = ~(ones & twos)
    ones &= mask
    twos &= mask

return ones

if name == 'main': arr = [1, 10, 1, 1] print(getSingle(arr))

C#

using System; using System.Collections.Generic;

class GfG { static int getSingle(int [] arr) { int ones = 0, twos = 0, mask;

    foreach (int num in arr) {
        
        
       // Update 'twos' with bits that are set in both 'ones' and 
        // current number. These are bits that have appeared twice so far.
        twos |= ones & num;
        
        // XOR current number with 'ones' to add bits appearing
        // odd number of times.If a bit has appeared once, it is set
        // if it's the second time, it gets unset.
        ones ^= num;
        
       // (ones & twos) gives bits that are set in both, meaning they 
       // have now appeared 3 times. ~(ones & twos) inverts it to create 
       // a mask where those bits are 0 (to be cleared), and others are 1.
        // Applying this mask on 'ones' and 'twos' removes the 
        // bits that have appeared three times.
        mask = ~(ones & twos);
        ones &= mask;
        twos &= mask;
    }

    return ones;
}

static void Main() {
    int [] arr = { 1, 10, 1, 1 };
    Console.WriteLine(getSingle(arr));
}

}

JavaScript

function getSingle(arr) { let ones = 0, twos = 0;

for (let num of arr) {
    
    
    // Update 'twos' with bits that are set in both 'ones' and 
    // current number. These are bits that have appeared twice so far.
    twos |= ones & num;
    
    // XOR current number with 'ones' to add bits appearing
    // odd number of times.If a bit has appeared once, it is set
    // if it's the second time, it gets unset.
    ones ^= num;
    
    // (ones & twos) gives bits that are set in both, meaning they 
    // have now appeared 3 times. ~(ones & twos) inverts it to create 
    // a mask where those bits are 0 (to be cleared), and others are 1.
    // Applying this mask on 'ones' and 'twos' removes the 
    // bits that have appeared three times.
    let mask = ~(ones & twos);
    ones &= mask;
    twos &= mask;
}

return ones;

}

const arr = [1, 10, 1, 1]; console.log(getSingle(arr));

`