修改数组的最大元素而不改变它们的位置?

时间:2011-05-13 17:21:59

标签: java arrays

我正在试图弄清楚如何修改数组的 n 最大元素而不修改它们的位置。例如,假设我有一个整数数组{5, 2, 3, 4, 8, 9, 1, 3}; 我想在两个最大的元素中添加1,使数组成为{5, 2, 3, 4, 9, 10, 1, 3}

当我尝试实现这些时,我能想到的所有这些方法最终会感到笨拙和不直观,并向我发出信号,表示我没有正确地思考它。例如,我可以使用TreeMap将数组的值作为键,将它们的索引作为值来查找最大值,修改它们,然后将它们放回到数组中,但是我必须实现自己的Comparator以相反的顺序对TreeMap进行排序(除非有一种我不知道的更简单的方法吗?)。我还在考虑将数组的内容复制到一个列表中,迭代 n 次,每次找到最大的元素及其索引,将修改后的最大元素放回到该索引的数组中,删除列表中的元素,并重复,但这对我来说感觉草率和低效。

有关如何处理此类问题的任何建议吗?

6 个答案:

答案 0 :(得分:3)

最简单的方法是扫描你的数组,并存储n个最高值的索引。增加这些元素的值。

这将是O(n)表现,我不认为任何更高级的方法可以击败它。

编辑添加:你可以最好在O(n)中对数组进行排序,在这种情况下你可以很快得到n个最高值,但要求是不要改变元素的位置,所以你'如果你想这样做,必须从数组的副本开始(或者保留订购信息,以便之后可以将所有内容都放回去)。

答案 1 :(得分:2)

您可能过度设计了解决此问题的方法:从头到尾扫描数组,并标记两个最大的元素。返回两个最大的元素并添加1。解决方案不应超过10行。

答案 2 :(得分:1)

  1. 循环数组并跟踪两个最大项的索引和值

    一个。初始化跟踪器,其中-1表示索引,MIN_INT表示值或数组的前两个值

    湾在循环的每个步骤中,将当前值与两个跟踪器值进行比较,并在必要时进行更新

  2. 增加两项
  3. 您选择的任何算法都应为O(n)。排序和n次传球都是过度杀伤。

答案 3 :(得分:0)

使用herehere(可以在线性时间内完成)找到第n个最大元素(称之为K),然后通过修改所有元素的数组> = K。

答案 4 :(得分:0)

我会做这样的事情

int[] indices = new int[2];
int[] maximas = new int[] { 0, 0 };
int[] data = new int[] { 3, 4, 5, 1, 9 };
for (int i = 0; i < 5; ++i)
{
    if (data[i] > maximas[1])
    {
            maximas[0] = maximas[1];
            maximas[1] = data[i];
            indices[0] = indices[1];
            indices[1] = i;
    } 
    else if (data[i] > maximas[0])
    {
            maximas[0] = data[i];
            indices[0] = i;
    }
} 

没有测试它,但我认为它应该工作:)

答案 5 :(得分:0)

我已经对此有所了解,但我无法达到最坏的效果:

O(n +(m-n)* n):( m> n)

最佳案例:

O(m):( m <= n)

其中m =值的数量,n =要搜索的最大值的数量

这是C#中的实现,但您可以轻松适应java:

        int n = 3;
        List<int> values = new List<int> {1,1,1,8,7,6,5};
        List<int> greatestIndexes = new List<int>();

        for (int i = 0; i < values.Count; i++) {
            if (greatestIndexes.Count < n)
            {
                greatestIndexes.Add(i);
            }
            else {
                int minIndex = -1, minValue = int.MaxValue;
                for (int j = 0; j < n; j++)
                {
                    if (values[greatestIndexes[j]] < values[i]) {

                        if (minValue > values[greatestIndexes[j]])
                        {
                            minValue = values[greatestIndexes[j]];
                            minIndex = j;
                        }
                    }
                }
                if (minIndex != -1)
                {
                    greatestIndexes.RemoveAt(minIndex);
                    greatestIndexes.Add(i);
                }
            }
        }

        foreach (var i in greatestIndexes) {
            Console.WriteLine(values[i]);
        }

输出:

8
7
6