Given Array of size n and a number k, find all elements that appear more than n/k times
Given an array of size n and an integer k, find all elements in the array that appear more than n/k times.
Examples:
Input: arr[ ] = [3, 4, 2, 2, 1, 2, 3, 3], k = 4
Output: [2, 3]
Explanation: Here n/k is 8/4 = 2, therefore 2 appears 3 times in the array that is greater than 2 and 3 appears 3 times in the array that is greater than 2Input: arr[ ] = [9, 10, 7, 9, 2, 9, 10], k = 3
Output: [9]
Explanation: Here n/k is 7/3 = 2, therefore 9 appears 3 times in the array that is greater than 2.
[Expected Solution] - Use Hashing - O(n) Time and O(n) Space
The idea is to pick all elements one by one. For every picked element, count its occurrences by traversing the array, if count becomes more than n/k, then print the element.
Follow the steps below to solve the problem:
- First, make a frequency map of all the elements in the array
- Then traverse the map and check the frequency of every element
- If the frequency is greater than n/k then print the element.
#include <bits/stdc++.h>
using namespace std;
void morethanNbyK(vector<int> &arr, int k)
{
int n = arr.size();
int x = n / k;
// unordered_map initialization
unordered_map<int, int> freq;
for (int i = 0; i < n; i++)
{
freq[arr[i]]++;
}
// Traversing the map
for (auto i : freq)
{
// Checking if value of a key-value pair
// is greater than x (where x=n/k)
if (i.second > x)
{
// Print the key of whose value
// is greater than x
cout << i.first << endl;
}
}
}
// Driver Code
int main()
{
vector<int> arr = {3, 4, 2, 2, 1, 2, 3, 3};
int k = 4;
morethanNbyK(arr, k);
return 0;
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void morethanNbyK(int[] arr, int k)
{
int n = arr.length;
int x = n / k;
// HashMap initialization
HashMap<Integer, Integer> freq = new HashMap<>();
for (int i = 0; i < n; i++) {
freq.put(arr[i],
freq.getOrDefault(arr[i], 0) + 1);
}
// Traversing the map
for (Map.Entry<Integer, Integer> entry :
freq.entrySet()) {
// Checking if value of a key-value pair
// is greater than x (where x=n/k)
if (entry.getValue() > x) {
// Print the key of whose value is greater
// than x
System.out.println(entry.getKey());
}
}
}
public static void main(String[] args)
{
int[] arr = { 3, 4, 2, 2, 1, 2, 3, 3 };
int k = 4;
morethanNbyK(arr, k);
}
}
def morethanNbyK(arr, k):
n = len(arr)
x = n // k
# dictionary initialization
freq = {}
for num in arr:
freq[num] = freq.get(num, 0) + 1
# Sort the dictionary keys
sorted_keys = sorted(freq.keys())
# Traversing the sorted keys
for key in sorted_keys:
# Checking if value of a key-value pair is greater than x
if freq[key] > x:
# Print the key whose value is greater than x
print(key)
arr = [3, 4, 2, 2, 1, 2, 3, 3]
k = 4
morethanNbyK(arr, k)
using System;
using System.Collections.Generic;
class Program {
public static void MoreThanNbyK(int[] arr, int k)
{
int n = arr.Length;
int x = n / k;
// Dictionary initialization
Dictionary<int, int> freq = new Dictionary<int, int>();
for (int i = 0; i < n; i++) {
if (freq.ContainsKey(arr[i])) {
freq[arr[i]]++;
}
else {
freq[arr[i]] = 1;
}
}
// Sort the dictionary keys
List<int> keys = new List<int>(freq.Keys);
keys.Sort();
// Traversing the sorted keys
foreach (var key in keys)
{
// Checking if the frequency of the element is greater than x (where x=n/k)
if (freq[key] > x) {
// Print the key whose value is greater than x
Console.WriteLine(key);
}
}
}
static void Main()
{
int[] arr = { 3, 4, 2, 2, 1, 2, 3, 3 };
int k = 4;
MoreThanNbyK(arr, k);
}
}
function morethanNbyK(arr, k)
{
const n = arr.length;
const x = Math.floor(n / k);
// object initialization
const freq = {};
for (let i = 0; i < n; i++) {
freq[arr[i]] = (freq[arr[i]] || 0) + 1;
}
// Traversing the object
for (const key in freq) {
// Checking if value of a key-value pair
// is greater than x (where x=n/k)
if (freq[key] > x) {
// Print the key of whose value is greater than
// x
console.log(key);
}
}
}
// Driver Code
const arr = [ 3, 4, 2, 2, 1, 2, 3, 3 ];
const k = 4;
morethanNbyK(arr, k);
Output
2 3
[Expected Solution for Small K] - Moore's Voting Algorithm - O(n x k) Time and O(k) Space
The idea is to apply Moore's Voting algorithm, as there can be at max k - 1 elements present in the array which appears more than n/k times so their will be k - 1 candidates. When we encounter an element which is one of our candidates then increment the count else decrement the count.
Illustration:
Consider k = 4, n = 9
Given array: 3 1 2 2 2 1 4 3 3i = 0
temp[] has one element {3} with count 1i = 1
temp[] has two elements {3, 1} with counts 1 and 1 respectivelyi = 2
temp[] has three elements, {3, 1, 2} with counts as 1, 1 and 1 respectively.i = 3
temp[] has three elements, {3, 1, 2} with counts as 1, 1 and 2 respectively.i = 4
temp[] has three elements, {3, 1, 2} with counts as 1, 1 and 3 respectively.i = 5
temp[] has three elements, {3, 1, 2 with counts as 1, 2 and 3 respectively.i = 6
temp[] has two elements, {1, 2} with counts as 1 and 2 respectively.i = 7
temp[] has three elements, {3, 1, 2} with counts as 1, 1 and 2 respectively.i = 8
temp[] has three elements, {3, 1, 2} with counts as 2, 1 and 2 respectively.
Follow the steps below to solve the problem:
- Create a temporary array of size (k - 1) to store elements and their counts (The output elements are going to be among these k-1 elements).
- Traverse through the input array and update temp[] (add/remove an element or increase/decrease count) for every traversed element. The array temp[] stores potential (k-1) candidates at every step.
- Iterate through final (k-1) potential candidates (stored in temp[]). or every element, check if it actually has counted of more than n/k.
#include <iostream>
#include <vector>
using namespace std;
// A structure to store an element and its current count
struct eleCount
{
int e; // Element
int c; // Count
};
// Prints elements with more
// than n/k occurrences in arr[]
// of size n. If there are no
// such elements, then it prints
// nothing.
void moreThanNdK(vector<int> &arr, int k)
{
int n = arr.size();
// k must be greater than
// 1 to get some output
if (k < 2)
return;
/* Step 1: Create a temporary
array (contains element
and count) of size k-1.
Initialize count of all
elements as 0 */
vector<eleCount> temp(k - 1);
for (int i = 0; i < k - 1; i++)
temp[i].c = 0, temp[i].e = -1;
/* Step 2: Process all
elements of input array */
for (int i = 0; i < n; i++)
{
int j;
/* If arr[i] is already present in
the element count array,
then increment its count
*/
for (j = 0; j < k - 1; j++)
{
if (temp[j].e == arr[i])
{
temp[j].c += 1;
break;
}
}
/* If arr[i] is not present in temp[] */
if (j == k - 1)
{
int l;
/* If there is position available
in temp[], then place arr[i] in
the first available position and
set count as 1*/
for (l = 0; l < k - 1; l++)
{
if (temp[l].c == 0)
{
temp[l].e = arr[i];
temp[l].c = 1;
break;
}
}
/* If all the position in the
temp[] are filled, then decrease
count of every element by 1 */
if (l == k - 1)
for (l = 0; l < k - 1; l++)
temp[l].c -= 1;
}
}
/*Step 3: Check actual counts of
* potential candidates in temp[]*/
for (int i = 0; i < k - 1; i++)
{
// Calculate actual count of elements
int ac = 0; // actual count
for (int j = 0; j < n; j++)
if (arr[j] == temp[i].e)
ac++;
// If actual count is more than n/k,
// then print it
if (ac > n / k)
cout << "Number:" << temp[i].e << " Count:" << ac << endl;
}
}
int main()
{
vector<int> arr = {3, 4, 2, 2, 1, 2, 3, 3};
int k = 4;
moreThanNdK(arr, k);
return 0;
}
// A structure to store an element and its current count
class EleCount {
int e; // Element
int c; // Count
}
public class Main {
// Prints elements with more than n/k occurrences in
// arr[] of size n. If there are no such elements, then
// it prints nothing.
public static void moreThanNdK(int[] arr, int k)
{
int n = arr.length;
// k must be greater than 1 to get some output
if (k < 2)
return;
// Step 1: Create a temporary array (contains
// element and count) of size k-1. Initialize count
// of all elements as 0
EleCount[] temp = new EleCount[k - 1];
for (int i = 0; i < k - 1; i++) {
temp[i] = new EleCount();
temp[i].c = 0;
temp[i].e = -1;
}
// Step 2: Process all elements of input array
for (int i = 0; i < n; i++) {
int j;
// If arr[i] is already present in the element
// count array, then increment its count
for (j = 0; j < k - 1; j++) {
if (temp[j].e == arr[i]) {
temp[j].c += 1;
break;
}
}
// If arr[i] is not present in temp[]
if (j == k - 1) {
int l;
// If there is position available in temp[],
// then place arr[i] in the first available
// position and set count as 1
for (l = 0; l < k - 1; l++) {
if (temp[l].c == 0) {
temp[l].e = arr[i];
temp[l].c = 1;
break;
}
}
// If all the position in the temp[] are
// filled, then decrease count of every
// element by 1
if (l == k - 1) {
for (l = 0; l < k - 1; l++) {
temp[l].c -= 1;
}
}
}
}
// Step 3: Check actual counts of potential
// candidates in temp[]
for (int i = 0; i < k - 1; i++) {
// Calculate actual count of elements
int ac = 0; // actual count
for (int j = 0; j < n; j++) {
if (arr[j] == temp[i].e)
ac++;
}
// If actual count is more than n/k, then print
// it
if (ac > n / k) {
System.out.println("Number: " + temp[i].e
+ " Count: " + ac);
}
}
}
// Driver code
public static void main(String[] args)
{
int[] arr = { 3, 4, 2, 2, 1, 2, 3, 3 };
int k = 4;
moreThanNdK(arr, k);
}
}
# A structure to store an element and its current count
class EleCount:
def __init__(self):
self.e = -1 # Element
self.c = 0 # Count
def moreThanNdK(arr, k):
n = len(arr)
# k must be greater than 1 to get some output
if k < 2:
return
# Step 1: Create a temporary array (contains
# element and count) of size k-1. Initialize count
# of all elements as 0
temp = [EleCount() for _ in range(k - 1)]
# Step 2: Process all elements of input array
for i in range(n):
j = 0
# If arr[i] is already present in the element
# count array, then increment its count
while j < k - 1:
if temp[j].e == arr[i]:
temp[j].c += 1
break
j += 1
# If arr[i] is not present in temp[]
if j == k - 1:
l = 0
# If there is position available in temp[],
# then place arr[i] in the first available
# position and set count as 1
while l < k - 1:
if temp[l].c == 0:
temp[l].e = arr[i]
temp[l].c = 1
break
l += 1
# If all the positions in temp[] are filled,
# then decrease count of every element by 1
if l == k - 1:
for l in range(k - 1):
temp[l].c -= 1
# Step 3: Check actual counts of potential
# candidates in temp[]
for i in range(k - 1):
ac = 0 # actual count
for j in range(n):
if arr[j] == temp[i].e:
ac += 1
# If actual count is more than n/k, then print
# it
if ac > n // k:
print(f"Number: {temp[i].e} Count: {ac}")
if __name__ == "__main__":
arr = [3, 4, 2, 2, 1, 2, 3, 3]
k = 4
moreThanNdK(arr, k)
using System;
class EleCount {
public int e; // Element
public int c; // Count
}
class MainClass {
// Prints elements with more than n/k occurrences in
// arr[] of size n. If there are no such elements, then
// it prints nothing.
public static void MoreThanNdK(int[] arr, int k)
{
int n = arr.Length;
// k must be greater than 1 to get some output
if (k < 2)
return;
// Step 1: Create a temporary array (contains
// element and count) of size k-1. Initialize count
// of all elements as 0
EleCount[] temp = new EleCount[k - 1];
for (int i = 0; i < k - 1; i++) {
temp[i] = new EleCount();
temp[i].c = 0;
temp[i].e = -1;
}
// Step 2: Process all elements of input array
for (int i = 0; i < n; i++) {
int j;
// If arr[i] is already present in the element
// count array, then increment its count
for (j = 0; j < k - 1; j++) {
if (temp[j].e == arr[i]) {
temp[j].c += 1;
break;
}
}
// If arr[i] is not present in temp[]
if (j == k - 1) {
int l;
// If there is position available in temp[],
// then place arr[i] in the first available
// position and set count as 1
for (l = 0; l < k - 1; l++) {
if (temp[l].c == 0) {
temp[l].e = arr[i];
temp[l].c = 1;
break;
}
}
// If all the position in the temp[] are
// filled, then decrease count of every
// element by 1
if (l == k - 1) {
for (l = 0; l < k - 1; l++) {
temp[l].c -= 1;
}
}
}
}
// Step 3: Check actual counts of potential
// candidates in temp[]
for (int i = 0; i < k - 1; i++) {
// Calculate actual count of elements
int ac = 0; // actual count
for (int j = 0; j < n; j++) {
if (arr[j] == temp[i].e)
ac++;
}
// If actual count is more than n/k, then print
// it
if (ac > n / k) {
Console.WriteLine("Number: " + temp[i].e
+ " Count: " + ac);
}
}
}
public static void Main(string[] args)
{
int[] arr = { 3, 4, 2, 2, 1, 2, 3, 3 };
int k = 4;
MoreThanNdK(arr, k);
}
}
// A structure to store an element and its current count
class EleCount {
constructor(e)
{
this.e = e; // Element
this.c = 0; // Count
}
}
// Prints elements with more
// than n/k occurrences in arr[]
// of size n. If there are no
// such elements, then it prints
// nothing.
function moreThanNdK(arr, k)
{
const n = arr.length;
// k must be greater than
// 1 to get some output
if (k < 2)
return;
/* Step 1: Create a temporary
array (contains element
and count) of size k-1.
Initialize count of all
elements as 0 */
const temp = Array.from({length : k - 1},
() => new EleCount(-1));
/* Step 2: Process all
elements of input array */
for (let i = 0; i < n; i++) {
let j;
/* If arr[i] is already present in
the element count array,
then increment its count
*/
for (j = 0; j < k - 1; j++) {
if (temp[j].e === arr[i]) {
temp[j].c += 1;
break;
}
}
/* If arr[i] is not present in temp[] */
if (j === k - 1) {
let l;
/* If there is position available
in temp[], then place arr[i] in
the first available position and
set count as 1*/
for (l = 0; l < k - 1; l++) {
if (temp[l].c === 0) {
temp[l].e = arr[i];
temp[l].c = 1;
break;
}
}
/* If all the position in the
temp[] are filled, then decrease
count of every element by 1 */
if (l === k - 1) {
for (l = 0; l < k - 1; l++) {
temp[l].c -= 1;
}
}
}
}
/*Step 3: Check actual counts of
* potential candidates in temp[]*/
for (let i = 0; i < k - 1; i++) {
// Calculate actual count of elements
let ac = 0; // actual count
for (let j = 0; j < n; j++) {
if (arr[j] === temp[i].e)
ac++;
}
// If actual count is more than n/k,
// then print it
if (ac > n / k) {
console.log(
`Number: ${temp[i].e} Count: ${ac}`);
}
}
}
/* Driver code */
const arr = [ 3, 4, 2, 2, 1, 2, 3, 3 ];
const k = 4;
moreThanNdK(arr, k);
Output
Number:3 Count:3 Number:2 Count:3
Time Complexity: O(n * k), Checking for each element of the array(size N) in the candidate array of size K
Auxiliary Space: O(k) Space required to store the candidates.
Using Built-In Counter in Python
This approach is same the first approach but here in python there is a counter() that calculates the frequency array.
- Count the frequencies of every element using Counter() function.
- Traverse the frequency array and print all the elements which occur at more than n/k times.
# Python3 implementation
from collections import Counter
# Function to find the number of array
# elements with frequency more than 1/k times
def printElements(arr, k):
# Counting frequency of every
# element using Counter
mp = Counter(arr)
# Traverse the map and print all
# the elements with occurrence
# more than 1/k times
for it in mp:
if mp[it] > len(arr) // k:
print(it)
# Driver code
if __name__ == '__main__':
arr = [3, 4, 2, 2, 1, 2, 3, 3]
k = 4
printElements(arr, k)
Output
3 2