Elements Appearing More Than n/k Times (original) (raw)

Given an array arr[] of size n and an integer k, determine the number of elements that appear more than n/k times in the array.

**Examples:

**Input: arr[ ] = [3, 4, 2, 2, 1, 2, 3, 3], k = 4
**Output: 2
**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 2

**Input: arr[ ] = [9, 10, 7, 9, 2, 9, 10], k = 3
**Output: 1
**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.

#include #include #include using namespace std;

int countOccurence(vector &arr, int k) { // compute array size and frequency threshold int n = arr.size(); int x = n / k;

// store frequency of each element
unordered_map<int, int> freq;
for (int num : arr)
    freq[num]++;

// count elements whose frequency exceeds n/k
int count = 0;
for (auto &p : freq)
    if (p.second > x)
        count++;

// return the final count
return count;

}

int main() { vector arr = {3, 4, 2, 2, 1, 2, 3, 3}; int k = 4; cout << countOccurence(arr, k); return 0; }

Java

import java.util.HashMap; import java.util.Map;

public class GFG {

static int countOccurence(int[] arr, int k) {
    // compute array size and frequency threshold
    int n = arr.length;
    int x = n / k;

    // store frequency of each element
    HashMap<Integer, Integer> freq = new HashMap<>();
    for (int num : arr)
        freq.put(num, freq.getOrDefault(num, 0) + 1);

    // count elements whose frequency exceeds n/k
    int count = 0;
    for (Map.Entry<Integer, Integer> e : freq.entrySet())
        if (e.getValue() > x)
            count++;

    // return the final count
    return count;
}

public static void main(String[] args) {
    int[] arr = {3, 4, 2, 2, 1, 2, 3, 3};
    int k = 4;
    System.out.println(countOccurence(arr, k));
}

}

Python

def countOccurence(arr, k): # compute array size and frequency threshold n = len(arr) x = n // k

# store frequency of each element
freq = {}
for num in arr:
    freq[num] = freq.get(num, 0) + 1

# count elements whose frequency exceeds n/k
count = 0
for val in freq.values():
    if val > x:
        count += 1

# return the final count
return count

if name == "main": arr = [3, 4, 2, 2, 1, 2, 3, 3] k = 4 print(countOccurence(arr, k))

C#

using System; using System.Collections.Generic;

class GFG { static int countOccurence(int[] arr, int k){ // compute array size and frequency threshold int n = arr.Length; int x = n / k;

    // store frequency of each element
    Dictionary<int, int> freq = new Dictionary<int, int>();
    foreach (int num in arr){
        if (freq.ContainsKey(num))
            freq[num]++;
        else
            freq[num] = 1;
    }

    // count elements whose frequency exceeds n/k
    int count = 0;
    foreach (var p in freq)
        if (p.Value > x)
            count++;

    // return the final count
    return count;
}

static void Main(){
    int[] arr = {3, 4, 2, 2, 1, 2, 3, 3};
    int k = 4;
    Console.WriteLine(countOccurence(arr, k));
}

}

JavaScript

function countOccurence(arr, k) { // compute array size and frequency threshold const n = arr.length; const x = Math.floor(n / k);

// store frequency of each element
const freq = {};
for (let num of arr)
    freq[num] = (freq[num] || 0) + 1;

// count elements whose frequency exceeds n/k
let count = 0;
for (let key in freq)
    if (freq[key] > x)
        count++;

// return the final count
return count;

}

// Driver Code const arr = [3, 4, 2, 2, 1, 2, 3, 3]; const k = 4; console.log(countOccurence(arr, k));

`

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

**i = 0
temp[] has one element {3} with count 1

**i = 1
temp[] has two elements {3, 1} with counts 1 and 1 respectively

**i = 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:

#include #include 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 &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 arr = {3, 4, 2, 2, 1, 2, 3, 3}; int k = 4; moreThanNdK(arr, k); return 0; }

Java

// 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);
}

}

Python

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)

C#

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);
}

}

` JavaScript ``

// 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: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>t</mi><mi>e</mi><mi>m</mi><mi>p</mi><mo stretchy="false">[</mo><mi>i</mi><mo stretchy="false">]</mo><mi mathvariant="normal">.</mi><mi>e</mi></mrow><mi>C</mi><mi>o</mi><mi>u</mi><mi>n</mi><mi>t</mi><mo>:</mo></mrow><annotation encoding="application/x-tex">{temp[i].e} Count: </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mopen">[</span><span class="mord mathnormal">i</span><span class="mclose">]</span><span class="mord">.</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord mathnormal">o</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span></span></span></span>{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.

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)

`