N/3 repeated number in an array with O(1) space

We are given a read only array of n integers. Find any element that appears more than n/3 times in the array in linear time and constant additional space. If no such element exists, return -1.

Examples:

Input : [10, 10, 20, 30, 10, 10]
Output : 10
10 occurs 4 times which is more than 6/3.

Input : [20, 30, 10, 10, 5, 4, 20, 1, 2]
Output : -1

The idea is based on Moore’s Voting algorithm.
We first find two candidates. Then we check if any of these two candidates is actually a majority. Below is the solution for above approach.



filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to find if any element appears
// more than n/3.
#include <bits/stdc++.h>
using namespace std;
  
int appearsNBy3(int arr[], int n)
{
    int count1 = 0, count2 = 0;
    int first=INT_MAX    , second=INT_MAX    ;
  
    for (int i = 0; i < n; i++) {
  
        // if this element is previously seen, 
        // increment count1.
        if (first == arr[i])
            count1++;
  
        // if this element is previously seen, 
        // increment count2.
        else if (second == arr[i])
            count2++;
      
        else if (count1 == 0) {
            count1++;
            first = arr[i];
        }
  
        else if (count2 == 0) {
            count2++;
            second = arr[i];
        }
  
        // if current element is different from
        // both the previously seen variables, 
        // decrement both the counts.
        else {
            count1--;
            count2--;
        }
    }
  
    count1 = 0;
    count2 = 0;
  
    // Again traverse the array and find the
    // actual counts.
    for (int i = 0; i < n; i++) {
        if (arr[i] == first)
            count1++;
  
        else if (arr[i] == second)
            count2++;
    }
  
    if (count1 > n / 3)
        return first;
  
    if (count2 > n / 3)
        return second;
  
    return -1;
}
  
int main()
{
    int arr[] = { 1, 2, 3, 1, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << appearsNBy3(arr, n) << endl;
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find if any element appears
// more than n/3.
class GFG {
      
    static int appearsNBy3(int arr[], int n)
    {
        int count1 = 0, count2 = 0;
          
        // take the integers as the maximum 
        // value of integer hoping the integer
        // would not be present in the array
        int first =  Integer.MIN_VALUE;;
        int second = Integer.MAX_VALUE;
      
        for (int i = 0; i < n; i++) {
      
            // if this element is previously
            // seen, increment count1.
            if (first == arr[i])
                count1++;
      
            // if this element is previously
            // seen, increment count2.
            else if (second == arr[i])
                count2++;
          
            else if (count1 == 0) {
                count1++;
                first = arr[i];
            }
      
            else if (count2 == 0) {
                count2++;
                second = arr[i];
            }
      
            // if current element is different
            // from both the previously seen
            // variables, decrement both the
            // counts.
            else {
                count1--;
                count2--;
            }
        }
      
        count1 = 0;
        count2 = 0;
      
        // Again traverse the array and 
        // find the actual counts.
        for (int i = 0; i < n; i++) {
            if (arr[i] == first)
                count1++;
      
            else if (arr[i] == second)
                count2++;
        }
      
        if (count1 > n / 3)
            return first;
      
        if (count2 > n / 3)
            return second;
      
        return -1;
    }
      
    // Driver code
    public static void main(String args[])
    {
        int arr[] = { 1, 2, 3, 1, 1 };
        int n = arr.length;
        System.out.println(appearsNBy3(arr, n));
          
    }
}
  
// This code is contributed by Arnab Kundu
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 program to find if 
# any element appears more than
# n/3.
import sys
  
def appearsNBy3(arr, n):
  
    count1 = 0
    count2 = 0
    first = sys.maxsize
    second = sys.maxsize
  
    for i in range(0, n): 
  
        # if this element is
        # previously seen, 
        # increment count1.
        if (first == arr[i]):
            count1 += 1
  
        # if this element is
        # previously seen, 
        # increment count2.
        elif (second == arr[i]):
            count2 += 1
      
        elif (count1 == 0):
            count1 += 1
            first = arr[i]
  
        elif (count2 == 0):
            count2 += 1
            second = arr[i]
          
  
        # if current element is 
        # different from both
        # the previously seen 
        # variables, decrement
        # both the counts.
        else:
            count1 -= 1
            count2 -= 1
          
      
  
    count1 = 0
    count2 = 0
  
    # Again traverse the array
    # and find the actual counts.
    for i in range(0, n): 
        if (arr[i] == first):
            count1 += 1
  
        elif (arr[i] == second):
            count2 += 1
      
  
    if (count1 > n / 3):
        return first
  
    if (count2 > n / 3):
        return second
  
    return -1
  
# Driver code
arr = [1, 2, 3, 1, 1 ]
n = len(arr) 
print(appearsNBy3(arr, n))
  
# This code is contributed by 
# Smitha
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find if any element appears
// more than n/3.
using System;
  
class GFG {
      
    static int appearsNBy3(int []arr, int n)
    {
        int count1 = 0, count2 = 0;
          
        // take the integers as the maximum
        // value of integer hoping the integer
        // would not be present in the array
        int first = int.MaxValue;
        int second = int.MaxValue;
      
        for (int i = 1; i < n; i++) {
      
            // if this element is previously 
            // seen, increment count1.
            if (first == arr[i])
                count1++;
      
            // if this element is previously 
            // seen, increment count2.
            else if (second == arr[i])
                count2++;
          
            else if (count1 == 0) {
                count1++;
                first = arr[i];
            }
      
            else if (count2 == 0) {
                count2++;
                second = arr[i];
            }
      
            // if current element is different
            // from both the previously seen 
            // variables, decrement both the
            // counts.
            else {
                count1--;
                count2--;
            }
        }
      
        count1 = 0;
        count2 = 0;
      
        // Again traverse the array and
        // find the actual counts.
        for (int i = 0; i < n; i++) {
            if (arr[i] == first)
                count1++;
      
            else if (arr[i] == second)
                count2++;
        }
      
        if (count1 > n / 3)
            return first;
      
        if (count2 > n / 3)
            return second;
      
        return -1;
    }
      
    // Driver code
    static public void Main(String []args)
    {
        int []arr = { 1, 2, 3, 1, 1 };
        int n = arr. Length;
        Console.WriteLine(appearsNBy3(arr, n));
    }
}
  
// This code is contributed by Arnab Kundu
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find if any element appears
// more than n/3.
  
function appearsNBy3( $arr$n)
{
     $count1 = 0; $count2 = 0;
    $first = PHP_INT_MAX ; $second = PHP_INT_MAX ;
  
    for ( $i = 0; $i < $n; $i++) {
  
        // if this element is previously seen, 
        // increment count1.
        if ($first == $arr[$i])
            $count1++;
  
        // if this element is previously seen, 
        // increment count2.
        else if ($second == $arr[$i])
            $count2++;
      
        else if ($count1 == 0) {
            $count1++;
            $first = $arr[$i];
        }
  
        else if ($count2 == 0) {
            $count2++;
            $second = $arr[$i];
        }
  
        // if current element is different from
        // both the previously seen variables, 
        // decrement both the counts.
        else {
            $count1--;
            $count2--;
        }
    }
  
    $count1 = 0;
    $count2 = 0;
  
    // Again traverse the array and find the
    // actual counts.
    for ($i = 0; $i < $n; $i++) {
        if ($arr[$i] == $first)
            $count1++;
  
        else if ($arr[$i] == $second)
            $count2++;
    }
  
    if ($count1 > $n / 3)
        return $first;
  
    if ($count2 > $n / 3)
        return $second;
  
    return -1;
}
  
// Driver code
$arr = array( 1, 2, 3, 1, 1 );
$n = count($arr);
echo appearsNBy3($arr, $n) ;
  
// This code is contributed by anuj_67.
?>
chevron_right

Output:
1

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Article Tags :
Practice Tags :