更新范围内的Array值

时间:2015-07-08 19:22:57

标签: arrays algorithm time-complexity

我有一个数组[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

请建议任何可以提高时间复杂度的算法。

2 个答案:

答案 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)次。

假设出价数量MO(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;
}

现在,你已经完成了。