我有一个大小为n + 1的数组,我希望存储购买n
项目的{i^th
索引存储成本i^th
项目的最低成本。
有m
个不同的卖家:每个卖家向商品L
提供商品R
(其中L
,R
> = 1和{{1 },L
< = n)每个费用为R
。
要创建成本最低的数组,我执行了以下操作:
C
构建此数组为for (int i=1; i<=m; i++) {
int L = L of i^th seller
int R = R of i^th seller
int C = selling price of i^th seller
for (int j=L; j<=R; j++) {
if (leastCost[j]==0 || leastCost[j]>C) {
leastCost[j]=C
}
}
,访问此数组为O(n*m)
。
对于非常大的O(1)
和n
值,是否有更好的方法来构建成本最低的数组?
也许不同的方法是不将它存储在数组和其他东西中,以便降低整体时间复杂度?
答案 0 :(得分:1)
你可以在这里使用某种形式的堆栈
如果L等于,则按L.和C desc排序所有卖家。
然后从第一个卖家(与李敏)开始
如果堆栈为空,则将其置于堆栈中。如果没有卖家
TypedArray
然后import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class CompileTest {
//A very naive way checking for any error
@Test(expected=java.lang.Error.class)
public void testForError() throws Exception {
this.is.not.a.statement;
}
//An example which check that we only find errors for regarding compilation errors.
@Test
public void expectNotCompilableMethod() {
try {
uncompilableMethod();
fail("No compile error detected");
} catch (Error e) {
assertTrue("Check for compile error message", e.getMessage().startsWith("Unresolved compilation problems"));
}
}
private void uncompilableMethod() {
do.bad.things;
}
}
和(Lj == Li)
(堆叠中)
如果有cost[Li] = C[i]
的条目,那么
如果Li++
和Lj == Li
跳过
如果Rj < Ri
和Cj > Ci
将此卖家添加到堆叠
如果Rj < Ri
和Cj < Ci
然后弹出当前卖家(i),请添加此卖家(j)并添加卖家(i)
答案 1 :(得分:1)
当然,我们可以做得比O(n * m)更好,解决方案也很简单。
以下是解决此问题的伪代码:
Construct a MIN-HEAP of the sellers based on their costs c.
Construct another array x[1...n] with its each element set to 0 initially.
Do the following initializations:
count=0
while(count < n)
{
S = EXTRACT_MIN(Heap)
if(count==0)
{
for(j=S.L to S.R)
{
leastCost[j]=S.c
++count
x[j]=S.R
}
}
else
{
for(j=S.L;j<=S.R;++j)
{
if(x[j]!=0)
{
i=x[j] and continue;
}
else
{
leastCost[j]=S.c
++count
x[j]=S.R
}
}
}
}
<强>解释强>
我们在这个问题上可以实现的最佳优化是我们跳过所有那些已经填充的数组索引,因为它们已经具有最低成本。
x辅助数组:数组x帮助我们跳过所有已填充的数组索引,因为:
x [i] 存储索引j,使得i到j已经在数组中填充的成本最低,因此这是使用条件语句的原因:
if(x[i]!=0)
{
i=x[i] and continue;
}
所以基本上它帮助我们直接跳到未填充的索引。
MIN-HEAP :它允许我们找到时间O(logm)中所有成本的最低成本c。
时间复杂度
因为我们访问数组最多n次因此访问数组: O(n)
构建堆需要 O(m)
在最糟糕的情况下,所有卖家都会对某些指数做出贡献,并且会有精确的m EXTRACT_MIN(堆)操作,并且每次都需要 O(logm)时间,所以时间是: O (M * 10gm的)强>
因此总时间复杂度= O(n + mlogm + m)= O(n + mlogm)。
顺便说一句,如果我使用C语言,我会使用struct for Seller,如果是Java,那么Seller.Feel的类可以免费查询。
答案 2 :(得分:0)
这个问题是一个经典问题Range minimum query,你可以使用Segment tree来获得一个时间复杂度为O(m log n)来创建树的解决方案,并为每个解决方案提供O(log n)查询。
更多详情:
我们使用树来表示从1到n的每个项目的最低价格。
对于每个卖家,我们更新树:
tree.update(L, R, C);
最后,要获取项i
的最小值,我们查询树:
tree.getMin(i, i);
由于update
和getMin
都具有时间复杂度O(log n),因此整个程序的时间复杂度为O(max(m,n)log n)。您不需要修改原始Segment树实现中的任何内容。