以下代码的总运行时间是多少:
我得出结论,这个代码需要执行O(N log N)次,当创建类时,循环需要花费O(N)时间来执行,其中下面的for循环需要log n时间。但我并不完全确定,这就是我在这里问的原因。
Z z = new Z(N);
for (int i = 0; i < N-1; i = i+2)
z.update(i,i+1);
Z级:
public class Z
{
int[] next, prev;
Z(int N)
{
prev = new int[N];
next = new int[N];
for (int i = 0; i<N; ++i)
// put element i in a list of its own
{
next[i] = i;
prev[i] = i;
}
}
int first(int i)
// return first element of list containing i
{
while (i != prev[i]) i = prev[i];
return i;
}
int last(int i)
// return last element of list containing i
{
while (i != next[i]) i = next[i];
return i;
}
void update(int i, int j)
{
int f = first(j);
int l = last(i);
next[l] = f;
prev[f] = l;
}
boolean query(int i, int j)
{
return last(i) == last(j);
}
}
答案 0 :(得分:1)
总运行时间仅为O(N)
。
构造函数的循环有O(N)
个步骤。
它会将next
/ prev
数组创建为[0, 1, ..., N]
。
z.update(i,i+1)
仅需O(1)
次。由于您仅针对每个update()
和i=i
致电j=i+1
,first(j)
和last(i)
将分别返回j
和i
在一般条件下无法分析first()
和last()
的预期复杂性,因为它们可能很容易包含无限循环(例如,如果0
调用next=[1,0]
1}})。但是,在给出的示例中,它们将始终完全跳过while
循环,因为对这些函数的每次调用都在尚未修改的索引上。
答案 1 :(得分:0)
你的for循环需要O(N)时间。你运行它总共N / 2次,因为你忽略了常量,这是N.总运行时间O(N ^ 2)。没有对数。
答案 2 :(得分:0)
以下是我的分析:
Z z = new Z(N); // O(n)
for (int i = 0; i < N-1; i = i+2) // O(n)
z.update(i,i+1); // O(1)
因此,总运行时间将为 O(n)。
int first(int i)
{
while (i != prev[i]) i = prev[i]; // O(1), i will always equal prev[i]
// for any input n > 0
return i;
}
int last(int i)
{
while (i != next[i]) i = next[i]; // O(1), i will always equal next[i]
// for any input n > 0
return i;
}
void update(int i, int j)
{
int f = first(j); // O(1)
int l = last(i); // O(1)
next[l] = f; // O(1)
prev[f] = l; // O(1)
}