原帖:搜狗笔试题
一个长度为n的数组a[0],a[1],...,a[n-1]。现在更新数组的各个元素,即a[0]变为a[1]到a[n-1]的积,a[1]变为a[0]和a[2]到a[n-1]的积,...,a[n-1]为a[0]到a[n-2]的积。
程序要求:
要求具有线性复杂度。不能使用除法运算符。
分析:
在看到此题时,由于所有元素的相似性,很容易想到要将数组中的所有元素想乘。但是得到所有元素的乘积后又能怎样呢?在不能使用乘法的前提下,毫无作为!
那我们来分析一下
a[0]' = a[1]*a[2]*a[3]*...*a[n-1]*a[n]
a[1] '=a[0]* a[2]*a[3]*....*a[n-1]*a[n]
......
a[k]'=a[0]*a[1]*a[2]*...*a[k-1]* a[k+1]*...*a[n-1]*a[n]
......
a[n]'=a[0]*a[1]*a[2]*...*a[n-1]
从上面a[k]'的公式中我们可以得到两部分成绩,一个是a[k]前面的乘积,一个是a[k]后面的乘积,这提示我们要分两部分进行计算。
在这里,我们使用一个b[2][n+1]的数组,存放我们需要的中间结果。
b[0][0] = a[0]
b[0][1] = a[0]*a[1]
b[0][2] = a[0]*a[1]*a[2]
.....
b[0][n-1] = a[0]*a[1]*a[2]*..*a[n-1]
b[1][n] = a[n]
b[1][n-1] = a[n]*a[n-1]
b[1][n-2] = a[n]*a[n-1]*a[n-2]
...
b[1][1] = a[n]*a[n-1]*a[n-2]*...*a[1]
那么,我们的结果
a[0]' = b[1][1]
a[1]' = b[0][0]*b[1][2]
a[2]' = b[0][1]*b[1][3]
a[3]' = b[0][2]*b[1][4]
...
a[k]' = b[0][k-1]*b[1][k+1]
....
a[n]' = b[0][n-1]
在程序中,我们先通过一遍的遍历,从前往后,不断计算得到b[0]数组,再遍历一次,从后往前计算b[1]数组中的各个数。在这个过程中可能计算量较大,注意在数比较大的时候使用大数乘法。通过两次遍历o(2n)的时间复杂度得到b数组,然后再通过o(n)的时间复杂度更新原数组。
在看到这个题时,也是毫无思路,但是找到了突破点的话就容易多了。