Algorithm 获取一个O(N)算法,以查找具有奇怪约束的数字集合的乘积
这是我最近参加采访时提出的一个问题,我觉得很有趣。假设int n=10 输入:数组Algorithm 获取一个O(N)算法,以查找具有奇怪约束的数字集合的乘积,algorithm,complexity-theory,big-o,Algorithm,Complexity Theory,Big O,这是我最近参加采访时提出的一个问题,我觉得很有趣。假设int n=10 输入:数组inta[10] 输出:一个数组浮点b[10] 要求: b[0]= a[1]*a[2]*...a[9]; // product of all numbers in a, other than a[0]; b[1]= a[0]*a[2]*...a[9]; // product of all numbers in a, other than a[1]; .... b[9]= a[0]*a[1]*...a[8]
inta[10]代码>
输出:一个数组<代码>浮点b[10]代码>
要求:
b[0]= a[1]*a[2]*...a[9]; // product of all numbers in a, other than a[0];
b[1]= a[0]*a[2]*...a[9]; // product of all numbers in a, other than a[1];
....
b[9]= a[0]*a[1]*...a[8]; // product of all numbers in a, other than a[9];
....
问题:如何在不使用除法运算符的情况下获得数组b
填充?使用O(n)
算法
我尝试了许多方法,但仍然徒劳无功。有什么想法吗?首先,计算所有左右产品:
left[i] = a[0]*a[1]*...*a[i]
right[i] = a[i]*a[i+1]*...*a[n-1]
请注意,left[i]==left[i-1]*a[i]
,因此可以在线性时间内计算left
数组。同样地,右
数组可以在线性时间内计算
从left
和right
开始,数组b
可以通过b[i]=left[i-1]*right[i+1]
在线性时间内计算,对于i==0
和i==n
,根据埃戈尔·斯克里普托诺夫的思想,我写了这段代码:更容易理解:
float l[n];
float r[n];
left[0] = 1;
right[n-1] = 1;
for (int i=1; i<n; i++)
{
l[i] = l[i-1]*a[i-1];
}
for (int i=n-2; i>=0; i--)
{
r[i] = r[i+1]*a[i+1];
}
for (int i=0; i<n; i++)
{
b[i] = l[i]*r[i];
}
float l[n];
浮动r[n];
左[0]=1;
右[n-1]=1;
对于(int i=1;i=0;i--)
{
r[i]=r[i+1]*a[i+1];
}
对于(inti=0;它真的很聪明!但是,它使用O(n)空间,这可能是个问题。我不明白。计算left[i]
和right[i]
是O(n)。计算left[0]
到left[n-1]
和right[0]
到right[n-1]
是O(n²)。你为什么认为它应该是O(n)?@Oswald-首先,计算所有的左[i]。其次,计算所有的右[i]。@Oswald-你可以用左[i]乘以a[i]从O(1)中的左[i]计算左[i+1]你可以使用指数运算吗?我想不可以,评论者可能会拒绝使用这个。