算法设计与分析: 2-2 众数问题

2-2 众数问题


问题描述

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。例如,S={1,2,2,2,3,5}。多重集S的众数是2,其重数为3。对于给定的n个自然数组成的多重集S,计算S的众数及其重数 。


数组实现

Java

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        int[] numbers = {1, 2, 2, 2, 3, 5};
//        int[] numbers = {1, 2, 2, 2, 3, 5, 1, 1, 1, 1};
//        int[] numbers = {1, 2, 2, 2, 3, 5, 1, 1, 1};
//        int[] numbers = {1, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5};
//        int[] numbers = {2, 2, 2, 2, 2, 2};
//        int[] numbers = {2};
//        int[] numbers = {2, 2};
//        int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 1, 2, 2, 3, 4, 5};

        int maxNum = Arrays.stream(numbers).max().getAsInt();

        int[] count = new int[maxNum+1];

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

        int tmpCount = 0;
        int tmpValue = 0;

        //loop by array numbers length
//        for(int i=0; i<numbers.length; i++){
//            if(count[numbers[i]] > tmpCount){
//                tmpCount = count[numbers[i]];
//                tmpValue = numbers[i];
//            }
//        }

        //loop by the maximum number in array numbers
        for(int i=0; i<=maxNum; i++){
            if(count[i] > tmpCount){
                tmpCount = count[i];
                tmpValue = i;
            }
        }

        System.out.println("The number: "+tmpValue+" appeared most times: "+tmpCount);
    }
}

分治法实现

Java

import java.util.Arrays;

public class Main {
//    private static int[] numbers = {1, 2, 2, 2, 3, 5};
//    private static int[] numbers = {1, 2, 2, 2, 3, 5, 1, 1, 1, 1};
//    private static int[] numbers = {1, 2, 2, 2, 3, 5, 1, 1, 1};
//    private static int[] numbers = {1, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5};
//    private static int[] numbers = {2, 2, 2, 2, 2, 2};
//    private static int[] numbers = {2};
//    private static int[] numbers = {2, 2};
    private static int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 1, 2, 2, 3, 4, 5};

    private static int leftest = 0;
    private static int rightest = numbers.length-1;
    private static int left, right;

    private static int count=0;
    private static int number;

    public static void main(String[] args) {

        Arrays.sort(numbers);

        mode(leftest, rightest);

        System.out.println("The number: "+number+" appeared most times: "+count);
    }

    private static void mode(int l, int r){

        int midIndex = getMidIndex(l, r);
        split(numbers, midIndex, l, r);

        if(count < right-left+1){
            count = right-left+1;
            number = numbers[midIndex];
        }
        if(left-l > count)
            mode(l, left-1);
        if(r-right > count)
            mode(right+1, r);
    }

    private static int getMidIndex(int l, int r){
        return (l+r)/2;
    }

    private static void split(int[] numbers, int midIndex, int l, int r)
    {
        left = midIndex;
        right = midIndex;

        while (left-1 >=l && numbers[--left] == numbers[midIndex]);
        while (right+1<=r && numbers[++right] == numbers[midIndex]);
        if(numbers[l] != numbers[midIndex])
            left++;
        if(numbers[r] != numbers[midIndex])
            right--;
    }
}

Map实现

Java

import java.util.*;

public class Main {

    public static void main(String[] args) {
        int[] numbers = {1, 2, 2, 2, 3, 5};
//        int[] numbers = {1, 2, 2, 2, 3, 5, 1, 1, 1, 1};
//        int[] numbers = {1, 2, 2, 2, 3, 5, 1, 1, 1};
//        int[] numbers = {1, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5};
//        int[] numbers = {2, 2, 2, 2, 2, 2};
//        int[] numbers = {2};
//        int[] numbers = {2, 2};
//        int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 1, 2, 2, 3, 4, 5};

        Map<Integer, Integer> kvMap = new HashMap<>();
        for (int i = 0; i < numbers.length; i++) {
            Integer v = kvMap.get(numbers[i]);
            kvMap.put(numbers[i], v == null ? 1 : v + 1);
        }

        //ArrayList
        List<Map.Entry<Integer, Integer>> entries = new ArrayList<>(kvMap.entrySet());

        // 对entries按出现频率从大到小排序
        Collections.sort(entries, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> e1, Map.Entry<Integer, Integer> e2) {
                return e2.getValue() - e1.getValue();
            }
        });

        System.out.println("The number: "+entries.get(0).getKey()+" appeared most times: "+entries.get(0).getValue());

        int size = entries.size();
        for (int i = 1; i < size; i++) {
            // 如果之后的entry与第一个entry的value相等,那么这个entry的键也是众数
            if (entries.get(i).getValue().equals(entries.get(0).getValue())) {
                System.out.println("The number: "+entries.get(i).getKey()+" appeared most times: "+entries.get(i).getValue());
            } else {
                break;
            }
        }
    }
}

Sample output

The number: 2 appeared most times: 3

Reference

王晓东《计算机算法设计与分析》(第3版)P41

猜你喜欢

转载自blog.csdn.net/IOIO_/article/details/80951973
今日推荐