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
- [Better Approach 1] Count Frequency of Elements Using Map - O(n) Time and O(n) Space
- [Better Approach 2] Using Math - O(n) Time and O(n) Space
- [Expected Approach 1] Using Bit Manipulation - O(n) Time and O(1) Space
- [Expected Approach 2] Using Bitmask - O(n) Time and O(1) Space
[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 -1if 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 0if 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, then3 *uniqueSumwould equaltotalSum. However, since one element appears only once, the difference3 * uniqueSum - totalSumequals 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 resultDriver 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:
- **Counting set bits: For each bit position (from least significant to most significant), iterate through the array and count the number of times the bit is set to 1 in each element. This gives us the sum of set bits for that particular position across all elements.
- **Modulo 3: Take the modulo 3 of the sum of set bits for each position. If the result is not 0, it means that the number that occurs only once has a 1 in that bit position, while the numbers that occur three times contribute in multiples of 3 and hence cancel out. For example, in the array
{1, 1, 1, 10}, the binary representation is:1 = 0001and10 = 1010. Counting set bits at each position: bit 0 appears 3 times →3 % 3 = 0, bit 1 appears once →1 % 3 = 1, bit 2 →0 % 3 = 0, bit 3 appears once →1 % 3 = 1. So the final binary result is1010, which is10, the unique number.
**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 resultarr = [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,
onesandtwos, to track the bits that appear an odd and even number of times, respectively. In each iteration, XOR the current element withonesto updateoneswith the bits that occur an odd number of times. Then, use a bitwise AND betweenonesand the current element to identify the common bits that appear exactly three times. These common bits are then removed from bothonesandtwosusing a bitwise AND with the negation of the common bits. After all iterations,oneswill hold the element that appears only once.
**Step by step Implementation:
- Initialize two integers
onesandtwosto track bits seen once and twice. - Iterate over each number in the array.
- Update
twoswith bits that are set in bothonesand the current number (twos |= ones & num). - Update
onesusing XOR with the current number (ones ^= num) to toggle bits based on odd occurrences. - Compute a mask by negating the common bits in
onesandtwos(mask = ~(ones & twos)). - Apply the mask to both
onesandtwosto remove bits that have appeared three times. - After the loop,
onesholds the bits of the number that appeared exactly once. C++ `
#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 onesif 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));
`