[java] Find the most popular element in int[] array

int[] a = new int[10]{1,2,3,4,5,6,7,7,7,7};

how can I write a method and return 7?

I want to keep it native without the help of lists, maps or other helpers. Only arrays[].

This question is related to java arrays

The answer is


public static void main(String[] args) {

    int[] myArray = {1,5,4,4,22,4,9,4,4,8};
    Map<Integer,Integer> arrayCounts = new HashMap<>();
    Integer popularCount  = 0;
    Integer popularValue = 0;

    for(int i = 0; i < myArray.length; i++) {
        Integer count = arrayCounts.get(myArray[i]);
        if (count == null) {
            count = 0;
        }
        arrayCounts.put(myArray[i], count == 0 ? 1 : ++count);
        if (count > popularCount) {
            popularCount = count;
            popularValue = myArray[i];
        }
    }

    System.out.println(popularValue + " --> " + popularCount);
}

public class MostFrequentIntegerInAnArray {

    public static void main(String[] args) {
        int[] items = new int[]{2,1,43,1,6,73,5,4,65,1,3,6,1,1};
        System.out.println("Most common item = "+getMostFrequentInt(items));
    }

    //Time Complexity = O(N)
    //Space Complexity = O(N)
    public static int getMostFrequentInt(int[] items){
        Map<Integer, Integer> itemsMap = new HashMap<Integer, Integer>(items.length);
        for(int item : items){
            if(!itemsMap.containsKey(item))
                itemsMap.put(item, 1);
            else
                itemsMap.put(item, itemsMap.get(item)+1);
        }

        int maxCount = Integer.MIN_VALUE;
        for(Entry<Integer, Integer> entry : itemsMap.entrySet()){
            if(entry.getValue() > maxCount)
                maxCount = entry.getValue();
        }
        return maxCount;
    }
}

This is the wrong syntax. When you create an anonymous array you MUST NOT give its size.

When you write the following code :

    new int[] {1,23,4,4,5,5,5};

You are here creating an anonymous int array whose size will be determined by the number of values that you provide in the curly braces.

You can assign this a reference as you have done, but this will be the correct syntax for the same :-

    int[] a = new int[]{1,2,3,4,5,6,7,7,7,7};

Now, just Sysout with proper index position:

    System.out.println(a[7]);

Try this answer. First, the data:

int[] a = {1,2,3,4,5,6,7,7,7,7};

Here, we build a map counting the number of times each number appears:

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i : a) {
    Integer count = map.get(i);
    map.put(i, count != null ? count+1 : 1);
}

Now, we find the number with the maximum frequency and return it:

Integer popular = Collections.max(map.entrySet(),
    new Comparator<Map.Entry<Integer, Integer>>() {
    @Override
    public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}).getKey();

As you can see, the most popular number is seven:

System.out.println(popular);
> 7

EDIT

Here's my answer without using maps, lists, etc. and using only arrays; although I'm sorting the array in-place. It's O(n log n) complexity, better than the O(n^2) accepted solution.

public int findPopular(int[] a) {

    if (a == null || a.length == 0)
        return 0;

    Arrays.sort(a);

    int previous = a[0];
    int popular = a[0];
    int count = 1;
    int maxCount = 1;

    for (int i = 1; i < a.length; i++) {
        if (a[i] == previous)
            count++;
        else {
            if (count > maxCount) {
                popular = a[i-1];
                maxCount = count;
            }
            previous = a[i];
            count = 1;
        }
    }

    return count > maxCount ? a[a.length-1] : popular;

}

below code can be put inside a main method

    // TODO Auto-generated method stub
    Integer[] a = { 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 2, 2, 2, 2, 3, 4, 2 };
    List<Integer> list = new ArrayList<Integer>(Arrays.asList(a));
    Set<Integer> set = new HashSet<Integer>(list);
    int highestSeq = 0;
    int seq = 0;
    for (int i : set) {
        int tempCount = 0;
        for (int l : list) {
            if (i == l) {
                tempCount = tempCount + 1;
            }
            if (tempCount > highestSeq) {
                highestSeq = tempCount;
                seq = i;
            }
        }

    }

    System.out.println("highest sequence is " + seq + " repeated for " + highestSeq);

You can count the occurrences of the different numbers, then look for the highest one. This is an example that uses a Map, but could relatively easily be adapted to native arrays.

Second largest element: Let us take example : [1,5,4,2,3] in this case, Second largest element will be 4.

  1. Sort the Array in descending order, once the sort done output will be A = [5,4,3,2,1]

  2. Get the Second Largest Element from the sorted array Using Index 1. A[1] -> Which will give the Second largest element 4.

private static int getMostOccuringElement(int[] A) { Map occuringMap = new HashMap();

    //count occurences
    for (int i = 0; i < A.length; i++) { 
        if (occuringMap.get(A[i]) != null) {
            int val = occuringMap.get(A[i]) + 1;
            occuringMap.put(A[i], val);
        } else {
            occuringMap.put(A[i], 1);
        }
    }

    //find maximum occurence
    int max = Integer.MIN_VALUE; 
    int element = -1;
    for (Map.Entry<Integer, Integer> entry : occuringMap.entrySet()) {
        if (entry.getValue() > max) {
            max = entry.getValue();
            element = entry.getKey();
        }
    }
    return element;
}

public class MostFrequentNumber {

    public MostFrequentNumber() {

    }

    int frequentNumber(List<Integer> list){

        int popular = 0;
        int holder = 0;

        for(Integer number: list) {
            int freq = Collections.frequency(list,number);

            if(holder < freq){
                holder = freq;
                popular = number;
            }
        }

       return popular;

    }

    public static void main(String[] args){

        int[] numbers = {4,6,2,5,4,7,6,4,7,7,7};

        List<Integer> list = new ArrayList<Integer>();

        for(Integer num : numbers){
            list.add(num);
        }


        MostFrequentNumber mostFrequentNumber = new MostFrequentNumber();

        System.out.println(mostFrequentNumber.frequentNumber(list));


    }
}

int largest = 0;
int k = 0;
for (int i = 0; i < n; i++) {
    int count = 1;
    for (int j = i + 1; j < n; j++) {
        if (a[i] == a[j]) {
            count++;
        }
    }
    if (count > largest) {
        k = a[i];
        largest = count;
    }
}

So here n is the length of the array, and a[] is your array.

First, take the first element and check how many times it is repeated and increase the counter (count) as to see how many times it occurs. Check if this maximum number of times that a number has so far occurred if yes, then change the largest variable (to store the maximum number of repetitions) and if you would like to store the variable as well, you can do so in another variable (here k).

I know this isn't the fastest, but definitely, the easiest way to understand


Best approach will be using map where key will be element and value will be the count of each element. Along with that keep an array of size that will contain the index of most popular element . Populate this array while map construction itself so that we don't have to iterate through map again.

Approach 2:-

If someone want to go with two loop, here is the improvisation from accepted answer where we don't have to start second loop from one every time

public class TestPopularElements {
    public static int getPopularElement(int[] a) {
        int count = 1, tempCount;
        int popular = a[0];
        int temp = 0;
        for (int i = 0; i < (a.length - 1); i++) {
            temp = a[i];
            tempCount = 0;
            for (int j = i+1; j < a.length; j++) {
                if (temp == a[j])
                    tempCount++;
            }
            if (tempCount > count) {
                popular = temp;
                count = tempCount;
            }
        }
        return popular;
    }

    public static void main(String[] args) {
        int a[] = new int[] {1,2,3,4,5,6,2,7,7,7};

        System.out.println("count is " +getPopularElement(a));
    }

}

Assuming your array is sorted (like the one you posted) you could simply iterate over the array and count the longest segment of elements, it's something like @narek.gevorgyan's post but without the awfully big array, and it uses the same amount of memory regardless of the array's size:

private static int getMostPopularElement(int[] a){
    int counter = 0, curr, maxvalue, maxcounter = -1;
    maxvalue = curr = a[0];

    for (int e : a){
        if (curr == e){
            counter++;
        } else {
            if (counter > maxcounter){
                maxcounter = counter;
                maxvalue = curr;
            }
            counter = 0;
            curr = e;
        }
    }
    if (counter > maxcounter){
        maxvalue = curr;
    }

    return maxvalue;
}


public static void main(String[] args) {
    System.out.println(getMostPopularElement(new int[]{1,2,3,4,5,6,7,7,7,7}));
}

If the array is not sorted, sort it with Arrays.sort(a);


public static int getMostCommonElement(int[] array) {

    Arrays.sort(array);

    int frequency = 1;
    int biggestFrequency = 1;
    int mostCommonElement = 0;

    for(int i=0; i<array.length-1; i++) {
        frequency = (array[i]==array[i+1]) ? frequency+1 : 1;
        if(frequency>biggestFrequency) {
            biggestFrequency = frequency; 
            mostCommonElement = array[i];
        }
    }

    return mostCommonElement;
}

package frequent;

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

public class Frequent_number {

    //Find the most frequent integer in an array

    public static void main(String[] args) {
        int arr[]= {1,2,3,4,3,2,2,3,3};

        System.out.println(getFrequent(arr));
        System.out.println(getFrequentBySorting(arr));
    }

    //Using Map , TC: O(n)  SC: O(n)
    static public int getFrequent(int arr[]){
        int ans=0;
        Map<Integer,Integer> m = new HashMap<>();
        for(int i:arr){
            if(m.containsKey(i)){
                m.put(i, m.get(i)+1);
            }else{
                m.put(i, 1);
            }
        }
        int maxVal=0;
        for(Integer in: m.keySet()){
            if(m.get(in)>maxVal){
                ans=in;
                maxVal = m.get(in);
            }
        }
        return ans;
    }

    //Sort the array and then find it TC: O(nlogn) SC: O(1)
    public static int getFrequentBySorting(int arr[]){
        int current=arr[0];
        int ansCount=0;
        int tempCount=0;
        int ans=current;
        for(int i:arr){
            if(i==current){
                tempCount++;
            }
            if(tempCount>ansCount){
                ansCount=tempCount;
                ans=i;
            }
            current=i;
        }
        return ans;
    }

}

import java.util.HashMap;
import java.util.Map;
import java.lang.Integer;
import java.util.Iterator;
public class FindMood {
    public static void main(String [] args){
    int arrayToCheckFrom [] = {1,2,4,4,5,5,5,3,3,3,3,3,3,3,3};
    Map map = new HashMap<Integer, Integer>();
    for(int i = 0 ; i < arrayToCheckFrom.length; i++){
    int sum = 0;
      for(int k = 0 ; k < arrayToCheckFrom.length ; k++){
          if(arrayToCheckFrom[i]==arrayToCheckFrom[k])
          sum += 1; 
      }
      map.put(arrayToCheckFrom[i], sum);
    }
    System.out.println(getMaxValue(map));
}
  public static Integer getMaxValue( Map<Integer,Integer> map){
        Map.Entry<Integer,Integer> maxEntry = null;
        Iterator iterator = map.entrySet().iterator();  
        while(iterator.hasNext()){
            Map.Entry<Integer,Integer> pair = (Map.Entry<Integer,Integer>) iterator.next();
            if(maxEntry == null || pair.getValue().compareTo(maxEntry.getValue())>0){
                maxEntry = pair; 
            } 
        }
        return maxEntry.getKey();
    }
}

import java.util.Scanner;


public class Mostrepeatednumber
{
    public static void main(String args[])
    {
        int most = 0;
        int temp=0;
        int count=0,tempcount;
        Scanner in=new Scanner(System.in);
        System.out.println("Enter any number");
        int n=in.nextInt();
        int arr[]=new int[n];
        System.out.print("Enter array value:");
        for(int i=0;i<=n-1;i++)
        {
            int n1=in.nextInt();
            arr[i]=n1;
        }
        //!!!!!!!! user input concept closed
        //logic can be started
        for(int j=0;j<=n-1;j++)
        {
        temp=arr[j];
        tempcount=0;
            for(int k=1;k<=n-1;k++)
                {
                if(temp==arr[k])
                    {
                        tempcount++;
                    }   
                        if(count<tempcount)
                            {
                                most=arr[k];
                                    count=tempcount;
                            }
                }

        }
        System.out.println(most);
    }

}

Assuming your int array is sorted, i would do...

int count = 0, occur = 0, high = 0, a;

for (a = 1; a < n.length; a++) {
    if (n[a - 1] == n[a]) {
       count++;
       if (count > occur) {
           occur = count;
           high = n[a];
       }
     } else {
        count = 0;
     }
}
System.out.println("highest occurence = " + high);

Seems like you are looking for the Mode value (Statistical Mode) , have a look at Apache's Docs for Statistical functions.


I hope this helps. public class Ideone { public static void main(String[] args) throws java.lang.Exception {

    int[] a = {1,2,3,4,5,6,7,7,7};
    int len = a.length;

    System.out.println(len);


    for (int i = 0; i <= len - 1; i++) {

        while (a[i] == a[i + 1]) {
            System.out.println(a[i]);

            break;
        }


    }


}

}


If you don't want to use a map, then just follow these steps:

  1. Sort the array (using Arrays.sort())
  2. Use a variable to hold the most popular element (mostPopular), a variable to hold its number of occurrences in the array (mostPopularCount), and a variable to hold the number of occurrences of the current number in the iteration (currentCount)
  3. Iterate through the array. If the current element is the same as mostPopular, increment currentCount. If not, reset currentCount to 1. If currentCount is > mostPopularCount, set mostPopularCount to currentCount, and mostPopular to the current element.

This one without maps:

public class Main {       

    public static void main(String[] args) {
        int[] a = new int[]{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7 };
        System.out.println(getMostPopularElement(a));        
    }

    private static int getMostPopularElement(int[] a) {             
        int maxElementIndex = getArrayMaximumElementIndex(a); 
        int[] b = new int[a[maxElementIndex] + 1]

        for (int i = 0; i < a.length; i++) {
            ++b[a[i]];
        }

        return getArrayMaximumElementIndex(b);
    }

    private static int getArrayMaximumElementIndex(int[] a) {
        int maxElementIndex = 0;

        for (int i = 1; i < a.length; i++) {
            if (a[i] >= a[maxElementIndex]) {
                maxElementIndex = i;
            }
        }

        return maxElementIndex;
    }      

}

You only have to change some code if your array can have elements which are < 0. And this algorithm is useful when your array items are not big numbers.


Array elements value should be less than the array length for this one:

public void findCounts(int[] arr, int n) {
    int i = 0;

    while (i < n) {
        if (arr[i] <= 0) {
            i++;
            continue;
        }

        int elementIndex = arr[i] - 1;

        if (arr[elementIndex] > 0) {
            arr[i] = arr[elementIndex];
            arr[elementIndex] = -1;
        }
        else {
            arr[elementIndex]--;
            arr[i] = 0;
            i++;
        }
    }

    Console.WriteLine("Below are counts of all elements");

    for (int j = 0; j < n; j++) {
        Console.WriteLine(j + 1 + "->" + Math.Abs(arr[j]));
    }
}

Time complexity of this will be O(N) and space complexity will be O(1).


Comparing two arrays, I Hope for that this is useful for you.

public static void main(String []args){

        int primerArray [] = {1,2,1,3,5};
        int arrayTow [] = {1,6,7,8};


       int numberMostRepetly =  validateArrays(primerArray,arrayTow);

       System.out.println(numberMostRepetly);


}


public static int validateArrays(int primerArray[], int arrayTow[]){

    int numVeces = 0;

    for(int i = 0; i< primerArray.length; i++){

        for(int c = i+1; c < primerArray.length; c++){

            if(primerArray[i] == primerArray[c]){
                numVeces = primerArray[c];
                // System.out.println("Numero que mas se repite");
                //System.out.println(numVeces);
            }
        }

        for(int a = 0; a < arrayTow.length; a++){

            if(numVeces == arrayTow[a]){
               // System.out.println(numVeces);
                return numVeces;
            }
        }
    }

    return 0;

}

Mine Linear O(N)

Using map to save all the differents elements found in the array and saving the number of times ocurred, then just getting the max from the map.

import java.util.HashMap;
import java.util.Map;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;

public class MosftOftenNumber {

    // for O(N) + map O(1) = O(N) 
    public static int mostOftenNumber(int[] a)
    {
        final Map m = new HashMap<Integer,Integer>();
        int max = 0;
        int element = 0;

        for (int i=0; i<a.length; i++){
            //initializing value for the map the value will have the counter of each element
            //first time one new number its found will be initialize with zero 
            if (m.get(a[i]) == null)
                m.put(a[i],0);

            //save each value from the array and increment the count each time its found
            m.put(a[i] , (Integer) m.get(a[i]) + 1);

            //check the value from each element and comparing with max
            if ( (Integer) m.get(a[i]) > max){
                max = (Integer) m.get(a[i]);
                element = a[i];
            }

        }
        System.out.println("Times repeated: " + max);
        return element;
    }

    public static int mostOftenNumberWithLambdas(int[] a)
    {
        Integer max = IntStream.of(a).boxed().max(Integer::compareTo).get();
        Integer coumtMax = Math.toIntExact(IntStream.of(a).boxed().filter(number -> number.equals(max)).count());
        System.out.println("Times repeated: " + coumtMax);
        return max;
    }

    public static void main(String args[]) {
//      int[] array = {1,1,2,1,1};
//      int[] array = {2,2,1,2,2};
        int[] array = {1,2,3,4,5,6,7,7,7,7};
        System.out.println("Most often number with loops: " + mostOftenNumber(array));
        System.out.println("Most often number with lambdas: " + mostOftenNumberWithLambdas(array));
    }

}

  1. Take a map to map element - > count
  2. Iterate through array and process the map
  3. Iterate through map and find out the popular

Using Java 8 Streams

int data[] = { 1, 5, 7, 4, 6, 2, 0, 1, 3, 2, 2 };
Map<Integer, Long> count = Arrays.stream(data)
    .boxed()
    .collect(Collectors.groupingBy(Function.identity(), counting()));

int max = count.entrySet().stream()
    .max((first, second) -> {
        return (int) (first.getValue() - second.getValue());
    })
    .get().getKey();

System.out.println(max);

Explanation

We convert the int[] data array to boxed Integer Stream. Then we collect by groupingBy on the element and use a secondary counting collector for counting after the groupBy.

Finally we sort the map of element -> count based on count again by using a stream and lambda comparator.