【问题标题】:Getting indexes of maximum number in array获取数组中最大数量的索引
【发布时间】:2017-10-20 09:41:16
【问题描述】:

我有一个包含排名数字的数组。

类似这样的:

0 4 2 0 1 0 4 2 0 4 0 2

这里0对应最低等级,max数字对应最高等级。可能有多个索引包含最高排名。

我想找到数组中所有最高排名的索引。我通过以下代码实现了:

import java.util.*;

class Index{

    public static void main(String[] args){

        int[] data = {0,4,2,0,1,0,4,2,0,4,0,2};
        int max = Arrays.stream(data).max().getAsInt();
        ArrayList<Integer> indexes = new ArrayList<Integer>();

        for(int i=0;i<12;i++){
            if(data[i]==max){
               indexes.add(i);
            }
        }

        for(int j=0;j<indexes.size();j++){
            System.out.print(indexes.get(j)+" ");   
        }
        System.out.println();
    }
}

我得到的结果是:1 6 9

还有比这更好的方法吗?

因为,就我而言,可能存在一个包含数百万个元素的数组,因此我在性能方面存在一些问题。

所以,

欢迎提出任何建议。

【问题讨论】:

  • 流式传输一些开销,因此用常规的for 循环替换该流行,以找到最大值,可能会稍微提高性能。否则,可能不会,但你为什么不分析代码,看看是否有任何弹出?
  • 您的问题是您对数组进行了两次迭代——一次是为了找到最大值,然后一次是为了找到它的所有实例。你真的只需要遍历数组一次。
  • 这是样例。我从一个函数中得到了一个数组,该函数的大小通常很大,这是整个执行的一部分,我想改进

标签: java arrays java-stream


【解决方案1】:

你在溪流路上……我建议你留在那里:)

int[] data = { 0, 4, 2, 0, -1, 0, 4, 2, 0, 4, 0, 2 };
int max = Arrays.stream(data).max().getAsInt();
int[] indices = IntStream.range(0, data.length).filter(i -> data[i] == max).toArray();

【讨论】:

    【解决方案2】:

    我看到你的程序通过数组 2 次。你可以试试这个: 遍历数组找到这个数组的最大值。当你找到一个最大值时,只需保存等于当前最大值及其值的所有其他元素。这样你只遍历数组一次。 这是一个示例:假设您有以下数组 {1,3,5,3,4,5} 并遍历它。您将首先将 1 保存为最大值,然后将 3 保存为 5,这是最大值这个数组。保存 5 后,您不会保存 3 或 4,但您将保存 5,因为它等于最大值。希望我有所帮助。

    【讨论】:

    • 这就是answer by Tim Biegeleisen 所做的。
    • 我知道,但我几乎在同一时间发布了它。我猜是它让我完成它的时间,他已经发布了它。
    【解决方案3】:

    一种方法是简单地沿数组进行一次传递,并跟踪所有最高编号的索引。如果当前条目小于目前看到的最高数字,则无操作。如果当前条目与看到的最高数字相同,则添加该索引。否则,我们看到了一个新的最高数字,我们应该丢弃旧的最高数字列表并开始一个新的。

    int[] data = {0,4,2,0,1,0,4,2,0,4,0,2};
    int max = Integer.MIN_VALUE;
    List<Integer> vals = new ArrayList<>();
    
    for (int i=0; i < data.length; ++i) {
        if (data[i] == max) {
            vals.add(i);
        }
        else if (data[i] > max) {
            vals.clear();
            vals.add(i);
            max = data[i];
        }
    }
    

    【讨论】:

    • 正是我所建议的,你只是快了一点!这是你能得到的最快速度,一次遍历整个数组就完成了。
    • 是的,这是正确的解决方案。我认为这个问题是重复的,这也是上次的正确答案。
    • 这将浪费一些时间从 max-so-far 值建立索引值,直到找到第一个最大值实例。由于这包括对索引进行装箱,它并不完全便宜,而且for 循环非常快,那么迭代的成本是否比建立和丢弃坏索引的成本高两倍?只有剖析可以说明。但是使用HashSet 肯定比使用ArrayList 更糟糕,因为永远不会收集到重复的索引值。
    • 如果你尝试在一个循环中从头部和尾部选择元素会更有效吗?
    • 为什么是HashSet?添加到索引集合中的索引始终是不同的。所以一个简单的ArrayList 应该会表现得更好,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2012-11-15
    • 2018-12-09
    • 1970-01-01
    相关资源
    最近更新 更多