用Java实现求一个数组中的出现次数最多的元素的个数

前些天做笔试题的时候,遇到这一道题:用Java实现求一个数组中的出现次数最多的元素的个数。但是时间比较紧,我想出了先排序,然后遍历一遍,相邻元素相等则累计,不同则重新累计,遍历完就可以得到相同元素出现最多的元素。自认为还可以,不过面试官笑着对我说:“加入数组的元素不能排序呢?”。哦,我把数组默认当做int数组了,假如数组是String类型的或者是其他的类型,就不能使用我这种方式了。

其实很容易想到一种方法,就是将相同的元素先各就各位,比如装在一个集合中,最后清点下哪个集合最大就可以了。为了使不同的类型数据可以复用,使用泛型(不过如果是基本类型数组就要转化为包装类型了):

/**
     * 使用ArrayList处理,如果是自己定义的类,则要合理重写equals方法
     * @param a
     * @return
     */
    public static <T> int getMostFrequentByArrayList(T a[]){
        if(a == null||a.length == 0){
            return 0;
        }
        int size  = a.length;
        int result = 0;
        //持有所有集合的集合。指定容量以免扩容带来的性能消耗,不过可能浪费空间
        ArrayList<ArrayList<T>> severalTempList = new ArrayList<ArrayList<T>>(size);

        for (int i = 0; i < size; i++) {
            boolean isAdd = false;
            T t = a[i];
            //遍历severalTempList每个ArrayList,找到t所属的则添加上去
            for(int j = 0;j < severalTempList.size();j++){
                ArrayList<T> singleTemps = severalTempList.get(j);
                if(singleTemps != null){
                    if(t.equals(singleTemps.get(0))){
                        singleTemps.add(t);
                        isAdd = true;
                    }
                }
            }
            //找不到t所属的则创建新的ArrayList添加到severalTempList,并将t添加到新的ArrayList
            if(!isAdd){
                ArrayList<T> singleTemps = new ArrayList<T>();
                singleTemps.add(t);
                severalTempList.add(singleTemps);
            }
        }

        //经过拆分后长度最大的集合
        ArrayList<T> largestList = severalTempList.get(0);
        //从索引为1开始就可以了
        for(int i = 1;i < severalTempList.size();i++){
            //通过遍历找到元素最多的集合
            if(severalTempList.get(i).size() > largestList.size()){
                largestList = severalTempList.get(i);
            }

            result = largestList.size();
        }

        return result;

    }

嗯,只要数组的长度不超过int的上限就行。。

test:

public static void main(String[] args){
        Integer a[] = {1,1,5,8,6,9,4,7,5,2,6,5,8,5,5,8,6,2};
        String s[] = {"s","s","s","t","t","t","t","t","c"};
        int resultString = MostFrequent.getMostFrequentByArrayList(s);
        int resultInteger = MostFrequent.getMostFrequentByArrayList(a);

        System.out.println(resultInteger);
        System.out.println(resultString);

    }

结果:
5
5

嗯,看来Integer和String都没问题。

不过通过遍历ArrayList将各个元素分配到对应的集合中的办法略显臃肿,性能也不算高。我们知道HashMap查询速度最快,而且使用LinkedList进行添加操作可以避免扩容带来的性能开销。所以这时候可以使用HashMap和LinkedList进行下优化:

/**
     * 使用HashMap提高性能。如果是自己定义的类,则要合理重写hashCode和equals方法
     * @param a
     * @return
     */
    public static <T> int getMostFrequentByMap(T a[]){
        if(a == null||a.length == 0){
            return 0;
        }
        int result = 0;
        int size = a.length;

        HashMap<T, LinkedList<T>> severalMap = new HashMap<>();

        for (int i = 0; i < size; i++) {
            T t = a[i];
            //以元素本身为键,元素分配到的LinkedList为值
            if(severalMap.get(t) != null){
                severalMap.get(t).add(t);
            }else{
                LinkedList<T> temp = new LinkedList<T>();
                temp.add(t);
                severalMap.put(t, temp);
            }
        }

        //指向长度最大的集合
        LinkedList<T> largestList = null;
        //找到元素最多的集合
        for (LinkedList<T> tempList : severalMap.values()) {
            if(largestList == null){
                largestList = tempList;
                continue;
            }

            if(tempList.size() > largestList.size()){
                largestList = tempList;
            }
            result = largestList.size();
        }   

        return result;

    }

你看,中间那段分配元素就不需要遍历了,直接HsshMap的查询就可以,代码简单速度还更快。

test:

public class Main {
    public static void main(String[] args){
        Integer a[] = {1,1,5,8,6,9,4,7,5,2,6,5,8,5,5,8,6,2};
        String s[] = {"s","s","s","t","t","t","t","t","c"};
        int resultInteger = MostFrequent.getMostFrequentByMap(a);
        int resultString = MostFrequent.getMostFrequentByMap(s);
        System.out.println(resultInteger);
        System.out.println(resultString);

    }

}

结果:
5
5

要注意的是,如果是自己定义的类,要正确重写hashCode和equals方法哦。

### 回答1: 可以使用 foreach 循环遍历数组,然后通过比较每个元素和目标值是否相等来找到匹配的元素。 以下是使用 foreach 循环查找数组中与给定数字相等的元素的示例代码: ``` <?php // 定义一个数组 $numbers = array(1, 2, 3, 4, 5); // 定义要查找的目标数字 $target = 3; // 遍历数组并查找匹配的元素 foreach ($numbers as $number) { if ($number == $target) { echo "找到了与目标数字相等的元素:$number"; break; } } ?> ``` 在上面的示例代码中,我们定义了一个数组 $numbers 和一个目标数字 $target。然后使用 foreach 循环遍历数组,并在每次循环中比较数组中元素和目标数字是否相等。如果找到匹配的元素,则输出该元素,并使用 break 语句跳出循环。 如果数组中存在多个与目标数字相等的元素,上面的代码只会输出第一个匹配的元素。如果想要输出所有匹配的元素,可以将 echo 语句移动到 if 语句的外面,并使用一个数组来保存匹配的元素,例如: ``` <?php // 定义一个数组 $numbers = array(1, 2, 3, 4, 5); // 定义要查找的目标数字 $target = 3; // 定义一个数组来保存匹配的元素 $matches = array(); // 遍历数组并查找匹配的元素 foreach ($numbers as $number) { if ($number == $target) { $matches[] = $number; } } // 输出所有匹配的元素 echo "找到了与目标数字相等的元素:"; foreach ($matches as $match) { echo "$match "; } ?> ``` 在上面的代码中,我们定义了一个数组 $matches 来保存所有与目标数字相等的元素。在循环中,如果找到匹配的元素,就将它添加到 $matches 数组中。然后使用 foreach 循环遍历 $matches 数组并输出所有匹配的元素。 ### 回答2: 使用foreach循环来计算数组对象中某个元素相同的个数可以采取以下步骤: 1. 定义一个变量count,并初始化为0,用于存储相同元素个数。 2. 使用foreach循环遍历数组对象。 3. 在循环体内,使用条件判断语句判断当前元素是否与目标元素相同。 4. 如果相同,将count加1。 5. 循环结束后,count的值就是数组对象中某个元素相同的个数。 具体代码如下: ```csharp // 假设我们要计算数组arr中元素为3的个数 int[] arr = { 1, 2, 3, 3, 4, 5, 3 }; int count = 0; int target = 3; foreach(int num in arr) { if(num == target) { count++; } } Console.WriteLine("数组中元素为3的个数为:" + count); ``` 这样就可以使用foreach循环计算数组对象中某个元素相同的个数了。以上代码执行结果为:数组中元素为3的个数为:3。表示数组arr中元素为3的个数为3个。 ### 回答3: 要用 foreach 得数组对象某个元素相同的个数,首先需要先遍历整个数组,再将目标元素数组中的每个元素进行比较,统计相同元素个数。 以下是一个使用 foreach 方法得数组对象某个元素相同个数的示例: ```java public class CountSameElement { public static void main(String[] args) { String[] array = {"apple", "banana", "apple", "orange", "apple", "kiwi"}; String target = "apple"; int count = 0; for (String element : array) { if (element.equals(target)) { count++; } } System.out.println("数组中与目标元素相同的个数为:" + count); } } ``` 以上示例中,我们定义了一个包含多个字符串的数组(array),目标元素(target)为"apple"。使用 foreach 循环遍历数组的每个元素,如果当前元素与目标元素相同,则计数器(count)加1。最后输出统计结果。 运行这个示例,输出结果为:"数组中与目标元素相同的个数为:3",表示数组中有3个元素与目标元素"apple"相同。 需要注意的是,此方法只能统计数组对象中某个元素出现次数,并且仅适用于比较简单的数据类型,如字符串、数字等。对于复杂的对象类型,需要重写 equals 方法来实现对象之间的比较。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值