Algorithm 获取一个O(N)算法,以查找具有奇怪约束的数字集合的乘积

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]

这是我最近参加采访时提出的一个问题,我觉得很有趣。假设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];  //  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]你可以使用指数运算吗?我想不可以,评论者可能会拒绝使用这个。