示例:开头的数组是6 6 9 7
,其中n=4
。
初始数组:6 6 9 7
第一次最高:9
数组更改为:6 6 9 3(因为arr [3] -4 = 3)
第二个最大值:9
数组更改为:6 6 5 3(因为arr [2] -4 = 5)
第三最高:6
数组更改为:6 2 5 3(因为arr [1] -4 = 2)
第四最高:6
数组更改为:2 2 5 3(由于arr [0] -4 = 2)
这可以在O(n ^ 2)中轻松实现,但是可以更高效地完成吗?
这是O(n ^ 2)解决方案的代码:
int arr[]={6,6,9,7};
int n=4;
for(int i=0;i<n;i++)
{
int max=0;
for(int j=0;j<n;j++)
{
if(arr[j]>arr[max])
max=j;
}
System.out.println(arr[max]);
arr[n-1-i]-=n;
}
答案 0 :(得分:0)
如果构造一个由最大堆和索引组成的单独的数据结构,则可以在O(n log n)中进行操作。这样的想法是,您可以按照相反的顺序遍历索引,每次调整最大堆中节点的值,然后在堆中上下移动它。堆的根元素将始终包含当前的最大数目。此解决方案将需要O(n)额外的内存。
如果要使用O(1)额外的内存就地执行此操作,则可以通过跟踪最大元素并仅在最大元素时搜索新的max来获得最佳情况时间O(n)变化。这会稍微改善平均情况,但最坏的情况仍然是O(n ^ 2)。