Skip to content
Related Articles

Related Articles

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

Improve Article
Save Article
Like Article
  • Difficulty Level : Hard
  • Last Updated : 27 May, 2021

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. 
 

C++




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

Java




// 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

Python 3




# 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

C#




// C# program to find if any element appears
// more than n/3.
using System;
 
public 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

PHP




<?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.
?>

Javascript




<script>
    // Javascript program to find if any element appears more than n/3.
     
    function appearsNBy3(arr, n)
    {
        let count1 = 0, count2 = 0;
          
        // take the integers as the maximum
        // value of integer hoping the integer
        // would not be present in the array
        let first = Number.MAX_VALUE;
        let second = Number.MAX_VALUE;
      
        for (let 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 (let i = 0; i < n; i++) {
            if (arr[i] == first)
                count1++;
      
            else if (arr[i] == second)
                count2++;
        }
      
        if (count1 > parseInt(n / 3, 10))
            return first;
      
        if (count2 > parseInt(n / 3, 10))
            return second;
      
        return -1;
    }
     
    let arr = [ 1, 2, 3, 1, 1 ];
    let n = arr.length;
    document.write(appearsNBy3(arr, n));
 
// This cde is contributed by divyeshrabadiya07.
</script>
Output: 
1

 

Complexity Analysis:

  • Time Complexity:  O(n)
    First pass of the algorithm takes complete traversal over the array contributing to O(n) and another O(n) is consumed in checking if count1 and count2 is greater than floor(n/3) times.
  • Space Complexity: O(1)
    As no extra space is required so space complexity is constant

My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!