提问人:akbiggs 提问时间:5/14/2011 最后编辑:Naftaliakbiggs 更新时间:5/14/2011 访问量:207
在不改变其位置的情况下修改数组中最大的元素?
Modifying the greatest elements of an array without changing their position?
问:
我试图弄清楚如何在不修改它们的位置的情况下修改数组的 n 个最大元素。例如,假设我有一个整数数组,我想将 1 添加到两个最大的元素中,使数组 .{5, 2, 3, 4, 8, 9, 1, 3};
{5, 2, 3, 4, 9, 10, 1, 3}
当我尝试实现它们时,我能想到的所有方法来做到这一点最终都会感到笨拙和不直观,向我发出信号,表明我没有正确地考虑它。例如,我可以使用一个 TreeMap,将数组的值作为键,将其索引作为值来查找最大值,修改它们,然后将它们扔回数组中,但是我必须实现我自己的比较器以相反的顺序对 TreeMap 进行排序(除非有我不知道的更简单的方法?我还考虑将数组的内容复制到列表中,遍历 n 次,每次都找到最大的元素及其索引,将修改后的最大元素放回该索引处的数组中,从列表中删除元素,然后重复,但这对我来说感觉草率且效率低下。
关于如何处理此类问题的任何建议?
答:
您可能过度设计了此问题的解决方案:从头到尾扫描数组,并标记两个最大的元素。返回到两个最大的元素,并在其中添加 1。解决方案不应超过 10 行。
评论
最简单的方法是扫描您的数组,并存储 n 个最高值的索引。递增这些元素的值。
这将是 O(n) 性能,我认为没有任何更高级的方法可以击败它。
编辑添加:您最多可以在 O(n) 中对数组进行就地排序,在这种情况下,您可以非常快速地获得 n 个最高值,但要求是不要更改元素的位置,因此如果您想这样做,则必须从数组的副本开始(或保留排序信息,以便之后可以将所有内容放回原处)。
评论
遍历数组并跟踪两个最大项目的索引和值
一个。使用 -1 初始化跟踪器作为索引,MIN_INT初始化跟踪器作为数组的值或前两个值
b.在循环的每个步骤中,将当前值与两个跟踪器值进行比较,并在必要时进行更新
- 递增这两个项目
为此,您选择的任何算法都应该是 O(n)。排序和 n 次传递是矫枉过正的。
使用 here 和 here 的技术找到第 n 个最大的元素(称为 K)(可以在线性时间内完成),然后遍历修改所有元素的数组 >= K。
评论
我会做这样的事情
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;
}
}
没有测试它,但我认为它应该:)
我对此有点强硬,但我不能实现比最坏的情况更多:
O( n + (m-n) * n ) : (m > n)
最佳案例:
O(米) : (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
评论