Given an integer array nums of size n. Return all elements which appear more than n/3 times in the array. The output can be returned in any order.
Input: nums = [1, 2, 1, 1, 3, 2]
Output: [1]
Explanation: Here, n / 3 = 6 / 3 = 2.
Therefore the elements appearing 3 or more times is : [1]
Input: nums = [1, 2, 1, 1, 3, 2, 2]
Output: [1, 2]
Explanation: Here, n / 3 = 7 / 3 = 2.
Therefore the elements appearing 3 or more times is : [1, 2]
Input: nums = [1, 2, 1, 1, 3, 2, 2, 3](Give the solution sorted in ascending order)
The naive way is to use nested loops to count the occurrences of each of the elements and if the count is greater than one third of the size of array, include the element in the answer.
To understand why there can't be more than two majority elements (elements that appear more than n/3 times) in an array of size n, let's use a simple mathematical reasoning. A majority element in this context is defined as an element that appears more than n/3 times in the array. For an element to be a majority element, it must appear more than n/3 times.
Let's assume there are more than two such majority elements. Let's denote these elements as A, B, and C.
Since each of these elements appears more than n/3 times, the combined frequency of these three elements would be:
frequency of 𝐴 + frequency of 𝐵 + frequency of 𝐶 > 𝑛/3 + 𝑛/3 + 𝑛/3 = 𝑛
Now, the total number of occurrences of all elements in the array cannot exceed n, the size of the array. This means the combined frequency of any three elements each appearing more than n/3 times would exceed the total size of the array, which is a contradiction. Therefore, it's mathematically impossible for there to be more than two elements in the array that each appear more than n/3 times.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find majority elements in an array
vector<int> majorityElementTwo(vector<int>& nums) {
// Size of the array
int n = nums.size();
// List of answers
vector<int> result;
for (int i = 0; i < n; i++) {
/*Checking if nums[i] is not
already part of the answer*/
if (result.size() == 0 || result[0] != nums[i]) {
int cnt = 0;
for (int j = 0; j < n; j++) {
// counting the frequency of nums[i]
if (nums[j] == nums[i]) {
cnt++;
}
}
// check if frquency is greater than n/3:
if (cnt > (n / 3))
result.push_back(nums[i]);
}
//if result size is equal to 2 break out of loop
if (result.size() == 2) break;
}
//return the majority elements
return result;
}
};
int main() {
vector<int> arr = {11, 33, 33, 11, 33, 11};
// Create an instance of Solution class
Solution sol;
vector<int> ans = sol.majorityElementTwo(arr);
// Print the majority elements found
cout << "The majority elements are: ";
for (auto it : ans) {
cout << it << " ";
}
cout << "\n";
return 0;
}
import java.util.*;
class Solution {
// Function to find majority elements in an array
public List<Integer> majorityElementTwo(int[] nums) {
// Size of the array
int n = nums.length;
// List of answers
List<Integer> result = new ArrayList<>();
for (int i = 0; i < n; i++) {
/* Checking if nums[i] is not
already part of the answer */
if (result.size() == 0 || result.get(0) != nums[i]) {
int cnt = 0;
for (int j = 0; j < n; j++) {
// counting the frequency of nums[i]
if (nums[j] == nums[i]) {
cnt++;
}
}
// check if frequency is greater than n/3
if (cnt > (n / 3)) {
result.add(nums[i]);
}
}
// if result size is equal to 2 break out of loop
if (result.size() == 2) {
break;
}
}
// return the majority elements
return result;
}
public static void main(String[] args) {
int[] arr = {11, 33, 33, 11, 33, 11};
// Create an instance of Solution class
Solution sol = new Solution();
List<Integer> ans = sol.majorityElementTwo(arr);
// Print the majority elements found
System.out.print("The majority elements are: ");
for (int it : ans) {
System.out.print(it + " ");
}
System.out.println();
}
}
from typing import List
class Solution:
# Function to find majority elements in an array
def majorityElementTwo(self, nums: List[int]) -> List[int]:
# Size of the array
n = len(nums)
# List of answers
result = []
for i in range(n):
""" Checking if nums[i] is not
already part of the answer """
if len(result) == 0 or result[0] != nums[i]:
cnt = 0
for j in range(n):
# counting the frequency of nums[i]
if nums[j] == nums[i]:
cnt += 1
# check if frequency is greater than n/3
if cnt > (n // 3):
result.append(nums[i])
# if result size is equal to 2 break out of loop
if len(result) == 2:
break
# return the majority elements
return result
if __name__ == "__main__":
arr = [11, 33, 33, 11, 33, 11]
# Create an instance of Solution class
sol = Solution()
ans = sol.majorityElementTwo(arr)
# Print the majority elements found
print("The majority elements are:", end=" ")
for it in ans:
print(it, end=" ")
print()
class Solution {
// Function to find majority elements in an array
majorityElementTwo(nums) {
// Size of the array
let n = nums.length;
// List of answers
let result = [];
for (let i = 0; i < n; i++) {
/* Checking if nums[i] is not
already part of the answer */
if (result.length === 0 || result[0] !== nums[i]) {
let cnt = 0;
for (let j = 0; j < n; j++) {
// counting the frequency of nums[i]
if (nums[j] === nums[i]) {
cnt++;
}
}
// check if frequency is greater than n/3
if (cnt > Math.floor(n / 3)) {
result.push(nums[i]);
}
}
// if result size is equal to 2 break out of loop
if (result.length === 2) {
break;
}
}
// return the majority elements
return result;
}
}
let arr = [11, 33, 33, 11, 33, 11];
// Create an instance of Solution class
let sol = new Solution();
let ans = sol.majorityElementTwo(arr);
// Print the majority elements found
console.log("The majority elements are: " + ans.join(" "));
A better idea is to use a data structure to reduce the number of look-up operations and hence to reduce the time complexity. Moreover, we have been calculating the count of the same element again and again, so reduce that also.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find majority elements in an array
vector<int> majorityElementTwo(vector<int>& nums) {
// size of the array
int n = nums.size();
// list of answers
vector<int> result;
// declaring a map
unordered_map<int, int> mpp;
// least occurrence of the majority element
int mini = int(n / 3) + 1;
// storing the elements with its occurrence
for (int i = 0; i < n; i++) {
mpp[nums[i]]++;
// checking if nums[i] is the majority element
if (mpp[nums[i]] == mini) {
result.push_back(nums[i]);
}
// if result size is equal to 2 break out of loop
if (result.size() == 2) {
break;
}
}
// return the majority elements
return result;
}
};
int main() {
vector<int> arr = {11, 33, 33, 11, 33, 11};
// Create an instance of Solution class
Solution sol;
vector<int> ans = sol.majorityElementTwo(arr);
// Print the majority elements found
cout << "The majority elements are: ";
for (auto it : ans) {
cout << it << " ";
}
cout << "\n";
return 0;
}
import java.util.*;
class Solution {
// Function to find majority elements in an array
public List<Integer> majorityElementTwo(int[] nums) {
// Size of the array
int n = nums.length;
// List of answers
List<Integer> result = new ArrayList<>();
// Declaring a map
Map<Integer, Integer> mpp = new HashMap<>();
// Least occurrence of the majority element
int mini = n / 3 + 1;
// Storing the elements with its occurrence
for (int i = 0; i < n; i++) {
mpp.put(nums[i], mpp.getOrDefault(nums[i], 0) + 1);
// Checking if nums[i] is the majority element
if (mpp.get(nums[i]) == mini) {
result.add(nums[i]);
}
// If result size is equal to 2 break out of loop
if (result.size() == 2) {
break;
}
}
// Return the majority elements
return result;
}
public static void main(String[] args) {
int[] arr = {11, 33, 33, 11, 33, 11};
// Create an instance of Solution class
Solution sol = new Solution();
List<Integer> ans = sol.majorityElementTwo(arr);
// Print the majority elements found
System.out.print("The majority elements are: ");
for (int it : ans) {
System.out.print(it + " ");
}
System.out.println();
}
}
from collections import defaultdict
from typing import List
class Solution:
# Function to find majority elements in an array
def majorityElementTwo(self, nums: List[int]) -> List[int]:
# Size of the array
n = len(nums)
# List of answers
result = []
# Declaring a map
mpp = defaultdict(int)
# Least occurrence of the majority element
mini = n // 3 + 1
# Storing the elements with its occurrence
for num in nums:
mpp[num] += 1
# Checking if num is the majority element
if mpp[num] == mini:
result.append(num)
# If result size is equal to 2 break out of loop
if len(result) == 2:
break
# Return the majority elements
return result
if __name__ == "__main__":
arr = [11, 33, 33, 11, 33, 11]
# Create an instance of Solution class
sol = Solution()
ans = sol.majorityElementTwo(arr)
# Print the majority elements found
print("The majority elements are:", *ans)
class Solution {
// Function to find majority elements in an array
majorityElementTwo(nums) {
// Size of the array
let n = nums.length;
// List of answers
let result = [];
// Declaring a map
let mpp = new Map();
// Least occurrence of the majority element
let mini = Math.floor(n / 3) + 1;
// Storing the elements with its occurrence
for (let i = 0; i < n; i++) {
let num = nums[i];
if (!mpp.has(num)) {
mpp.set(num, 0);
}
mpp.set(num, mpp.get(num) + 1);
// Checking if num is the majority element
if (mpp.get(num) === mini) {
result.push(num);
}
// If result size is equal to 2 break out of loop
if (result.length === 2) {
break;
}
}
// Return the majority elements
return result;
}
}
let arr = [11, 33, 33, 11, 33, 11];
// Create an instance of Solution class
let sol = new Solution();
let ans = sol.majorityElementTwo(arr);
// Print the majority elements found
console.log("The majority elements are:", ans.join(" "));
Imagine you're in charge of a small party with 30 guests. Each guest has a favorite fruit, and you want to find out which fruits are most popular. Specifically, you want to know if any fruit is liked by more than a third of the guests (so more than 10 people).
As guests arrive, note their favorite fruit. Keep track of up to two different fruits at a time and how many people like each of these fruits. If a new guest likes one of the fruits you're tracking, increase the count for that fruit. If they like a different fruit and you have room to track another, you start tracking that fruit. If both tracking slots are full and the new fruit is different, you reduce the count for both tracked fruits. After all guests have arrived, you have two potential popular fruits. To confirm, go through the list one more time and count how many guests like each of these fruits.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find majority elements in an array
vector<int> majorityElementTwo(vector<int>& nums) {
// Size of the array
int n = nums.size();
// Counts for elements el1 and el2
int cnt1 = 0, cnt2 = 0;
/*Initialize Element 1 and
Element 2 with INT_MIN value*/
int el1 = INT_MIN, el2 = INT_MIN;
/*Find the potential candidates using
Boyer Moore's Voting Algorithm*/
for (int i = 0; i < n; i++) {
if (cnt1 == 0 && el2 != nums[i]) {
cnt1 = 1;
// Initialize el1 as nums[i]
el1 = nums[i];
}
else if (cnt2 == 0 && el1 != nums[i]) {
cnt2 = 1;
// Initialize el2 as nums[i]
el2 = nums[i];
}
else if (nums[i] == el1) {
// Increment count for el1
cnt1++;
}
else if (nums[i] == el2) {
// Increment count for el2
cnt2++;
}
else {
// Decrement count for el1
cnt1--;
// Decrement count for el2
cnt2--;
}
}
//Validate the candidates by counting occurrences in nums
//Reset counts for el1 and el2
cnt1 = 0, cnt2 = 0;
for (int i = 0; i < n; i++) {
if (nums[i] == el1) {
// Count occurrences of el1
cnt1++;
}
if (nums[i] == el2) {
// Count occurrences of el2
cnt2++;
}
}
/* Determine the minimum count
required for a majority element*/
int mini = n / 3 + 1;
// List of answers
vector<int> result;
/*Add elements to the result vector
if they appear more than n/3 times*/
if (cnt1 >= mini) {
result.push_back(el1);
}
if (cnt2 >= mini && el1 != el2) {
// Avoid adding duplicate if el1 == el2
result.push_back(el2);
}
// Uncomment the following line if you want to sort the answer array
// sort(result.begin(), result.end()); // TC --> O(2*log2) ~ O(1);
//return the majority elements
return result;
}
};
int main() {
vector<int> arr = {11, 33, 33, 11, 33, 11};
// Create an instance of Solution class
Solution sol;
vector<int> ans = sol.majorityElementTwo(arr);
// Print the majority elements found
cout << "The majority elements are: ";
for (auto it : ans) {
cout << it << " ";
}
cout << "\n";
return 0;
}
import java.util.*;
class Solution {
// Function to find majority elements in an array
public List<Integer> majorityElementTwo(int[] nums) {
// Size of the array
int n = nums.length;
// Counts for elements el1 and el2
int cnt1 = 0, cnt2 = 0;
/*Initialize Element 1 and
Element 2 with INT_MIN value*/
int el1 = Integer.MIN_VALUE, el2 = Integer.MIN_VALUE;
/*Find the potential candidates using
Boyer Moore's Voting Algorithm*/
for (int i = 0; i < n; i++) {
if (cnt1 == 0 && el2 != nums[i]) {
cnt1 = 1;
// Initialize el1 as nums[i]
el1 = nums[i];
} else if (cnt2 == 0 && el1 != nums[i]) {
cnt2 = 1;
// Initialize el2 as nums[i]
el2 = nums[i];
} else if (nums[i] == el1) {
// Increment count for el1
cnt1++;
} else if (nums[i] == el2) {
// Increment count for el2
cnt2++;
} else {
// Decrement count for el1
cnt1--;
// Decrement count for el2
cnt2--;
}
}
//Validate the candidates by counting occurrences in nums:
//Reset counts for el1 and el2
cnt1 = 0; cnt2 = 0;
for (int i = 0; i < n; i++) {
if (nums[i] == el1) {
// Count occurrences of el1
cnt1++;
}
if (nums[i] == el2) {
// Count occurrences of el2
cnt2++;
}
}
/* Determine the minimum count
required for a majority element*/
int mini = n / 3 + 1;
// List of answers
List<Integer> result = new ArrayList<>();
/*Add elements to the result vector
if they appear more than n/3 times*/
if (cnt1 >= mini) {
result.add(el1);
}
if (cnt2 >= mini && el1 != el2) {
// Avoid adding duplicate if el1 == el2
result.add(el2);
}
// Uncomment the following line if you want to sort the answer array
// Collections.sort(result); // TC --> O(2*log2) ~ O(1);
//return the majority elements
return result;
}
public static void main(String[] args) {
int[] arr = {11, 33, 33, 11, 33, 11};
// Create an instance of Solution class
Solution sol = new Solution();
List<Integer> ans = sol.majorityElementTwo(arr);
// Print the majority elements found
System.out.print("The majority elements are: ");
for (int it : ans) {
System.out.print(it + " ");
}
System.out.println();
}
}
from typing import List
class Solution:
# Function to find majority elements in an array
def majorityElementTwo(self, nums: List[int]) -> List[int]:
# Size of the array
n = len(nums)
# Counts for elements el1 and el2
cnt1, cnt2 = 0, 0
"""Initialize Element 1 and
Element 2 with INT_MIN value"""
el1, el2 = float('-inf'), float('-inf')
"""Find the potential candidates using
Boyer Moore's Voting Algorithm"""
for num in nums:
if cnt1 == 0 and el2 != num:
cnt1 = 1
# Initialize el1 as num
el1 = num
elif cnt2 == 0 and el1 != num:
cnt2 = 1
# Initialize el2 as num
el2 = num
elif num == el1:
# Increment count for el1
cnt1 += 1
elif num == el2:
# Increment count for el2
cnt2 += 1
else:
# Decrement count for el1
cnt1 -= 1
# Decrement count for el2
cnt2 -= 1
#Validate the candidates by counting occurrences in nums
#Reset counts for el1 and el2
cnt1, cnt2 = 0, 0
for num in nums:
if num == el1:
# Count occurrences of el1
cnt1 += 1
if num == el2:
# Count occurrences of el2
cnt2 += 1
""" Determine the minimum count
required for a majority element"""
mini = n // 3 + 1
# List of answers
result = []
"""Add elements to the result list
if they appear more than n/3 times"""
if cnt1 >= mini:
result.append(el1)
if cnt2 >= mini and el1 != el2:
# Avoid adding duplicate if el1 == el2
result.append(el2)
# Uncomment the following line if you want to sort the answer list
# result.sort() # TC --> O(2*log2) ~ O(1);
#return the majority elements
return result
if __name__ == "__main__":
arr = [11, 33, 33, 11, 33, 11]
# Create an instance of Solution class
sol = Solution()
ans = sol.majorityElementTwo(arr)
# Print the majority elements found
print("The majority elements are:", *ans)
class Solution {
// Function to find majority elements in an array
majorityElementTwo(nums) {
// Size of the array
let n = nums.length;
// Counts for elements el1 and el2
let cnt1 = 0, cnt2 = 0;
/* Initialize Element 1 and
Element 2 with INT_MIN value */
let el1 = Number.MIN_SAFE_INTEGER, el2 = Number.MIN_SAFE_INTEGER;
/* Find the potential candidates using
Boyer Moore's Voting Algorithm */
for (let i = 0; i < n; i++) {
if (cnt1 === 0 && el2 !== nums[i]) {
cnt1 = 1;
// Initialize el1 as nums[i]
el1 = nums[i];
} else if (cnt2 === 0 && el1 !== nums[i]) {
cnt2 = 1;
// Initialize el2 as nums[i]
el2 = nums[i];
} else if (nums[i] === el1) {
// Increment count for el1
cnt1++;
} else if (nums[i] === el2) {
// Increment count for el2
cnt2++;
} else {
// Decrement count for el1
cnt1--;
// Decrement count for el2
cnt2--;
}
}
//Validate the candidates by counting occurrences in nums
//Reset counts for el1 and el2
cnt1 = 0; cnt2 = 0;
for (let i = 0; i < n; i++) {
if (nums[i] === el1) {
// Count occurrences of el1
cnt1++;
}
if (nums[i] === el2) {
// Count occurrences of el2
cnt2++;
}
}
/* Determine the minimum count
required for a majority element */
let mini = Math.floor(n / 3) + 1;
// List of answers
let result = [];
/* Add elements to the result array
if they appear more than n/3 times */
if (cnt1 >= mini) {
result.push(el1);
}
if (cnt2 >= mini && el1 !== el2) {
// Avoid adding duplicate if el1 == el2
result.push(el2);
}
// Uncomment the following line if you want to sort the answer array
// result.sort((a, b) => a - b); // TC --> O(2*log2) ~ O(1);
//return the majority elements
return result;
}
}
// Main function to test the solution
let arr = [11, 33, 33, 11, 33, 11];
//Create an instance of Solution class
let sol = new Solution();
let ans = sol.majorityElementTwo(arr);
// Print the majority elements found
console.log("The majority elements are:", ...ans);
Q: Why can there be at most two elements appearing more than n/3 times?
A: If there were 3 elements appearing more than n/3 times, their total count would exceed n, which is impossible.
Q: Why is sorting less efficient?
A: Sorting takes O(n log n), which is slower than O(n) Boyer-Moore.
Q: How would you modify this for elements appearing more than n/k times?
A: Use k-1 candidates in Boyer-Moore Voting Algorithm instead of just 2.
Q: Can this problem be solved using bitwise operations?
A: Yes, count each bit position and reconstruct the elements.