我有一个数组[1:N],它被初始化为MAXIMUM-VALUE。
我必须维护一个系统,其中每个用户/投标人给出范围(低,高)元素及其对该范围的每个元素的出价。他对此范围内每个元素的出价值是相同的。我必须为所有不同的元素获得最低出价。在一些出价之后,我必须得到数组的值。
我编写了一个代码,但它运行在O(n ^ 2)中。
while(number_of_bids--)
{
cin>>low>>high>>bid_value;
while(low<=high && low<=N)
{
vs[low].cost=min(vs[low].cost,bid_value);
low++;
}
}
例如,对于数组[1:10],以及出价是:
1 2 65
2 4 58
3 7 86
1 9 88
然后数组的值变为:
65,58,58,58,86,86,86,88,88,MAXIMUM-VALUE
请建议任何可以提高时间复杂度的算法。
答案 0 :(得分:2)
您可以使用平衡二叉树(c ++或Java中的有序集)在O(N*lg N)
中执行此操作。
首先准备一份表格事件清单:&#34;索引:第i个出价开始&#34;或&#34;指数:第k个投标结束&#34; (指数是范围的低或高部分)。按索引对列表进行排序。
创建一个树来存储按出价值排序的出价。
从左到右遍历数组。每当阵列中存在当前单元格的事件(或事件)时(事件存储在单独的排序列表中),就可以从树中添加或删除事件中引用的出价。对于每个单元格,在树中找到最低出价。将此值存储在单元格中。如果树为空,请将单元格保留为MAXIMUM-VALUE
。
这里的一个微妙之处是处理出价重复。您只能在树中存储出价值(不带范围),但是您的数据结构必须允许重复(多个集合),并且在删除出价时务必仅删除该值的一次出现。或者,您可以存储不同的出价标识符,例如它们在输入中的位置,但按出价值对树进行排序。
让N
为数组的大小,M
为出价数。
此算法为您提供最差O(N*lg M + M*lg M)
时间。
出价事件的排序显然是O(M*lg M)
。
然后主循环有O(N)
次迭代(数组的大小),对于每个单元格,我们进行单次查找以找到O(lg M)
的最小出价。
我们还必须处理O(M)
个活动,例如添加或删除出价,每个活动也需要O(lg M)
次。
假设出价数量M
为O(N)
(仅使用此假设,您的解决方案为O(N^2)
),算法总是为O(N*lg N)
。
答案 1 :(得分:2)
您可以使用索引的结构和映射来完成。 这是解释: 首先构建范围和出价结构的数组/向量。 为:
struct node{
int bid;
int left;
int right;
}arr[10005];
现在在数组中输入出价。然后使用bid上的比较器对数组进行排序。 作为:
sort(arr,arr+n,comp)
// comparator function could be as :
bool comp(node c,node d)
{
return c.bid<d.bid;
}
现在创建一个辅助数组来映射索引并将其初始化为-1。然后遍历结构数组并将辅助阵列填充到右边的数字。为:
int flag=0,count=0;
for(int i=0;i<n;i++){
flag=arr[i].left;
while(flag<n && flag<=arr[i].right){
if(aux_array[flag]==-1){
aux_array[flag] = arr[i].right;
flag++;count++;
}
else {
flag=aux_array[flag]+1;
}
if(count>=n) break;
}
if(count>=n) break;
}
现在,你已经完成了。