google面试题一道

最近很忙,是在木有时间上来写技术博客了。人又变懒了啊~

今天抽点时间,上来讨论一道google的面试题吧~

题目是:给你一个数组 A [ 1 .. n ] ,请你在 O ( n ) 的时间里构造一个新的数组 B [ 1 .. n ] ,使得 B [ i ] = A [ 1 ] * A [ 2 ] * ... * A [ n ]/A [ i ] 。你不能使用除法运算。

思路和解答:这一题实则很简单。有过基本编程思维训练的人都知道,降低时间复杂度,肯定会在空间上有所牺牲。并且,这种类型的题目,最重要的就是要避免重复计算,即必须用额外的空间来储存已经计算得到的记过。这点和尾递归的优化以及动态规划思想有类似之处。

实际上,因为B [ i ] = A [ 1 ] * A [ 2 ] * ... * A [ n ]/A [ i ]

换一种写法,即B [ i ] = A [ 1 ] * ... * A [ i - 1 ] * A [ i + 1 ] * ... * A [ n ]

可以看到上述式子分为两个部分,前半部分是1到i-1的乘积,后者是i+1到n的乘积。

那么我们就可以设置两个数组:

S [ i ] = A [ 1 ] * ... * A [ i – 1 ]

T [ i ] = A [ i + 1 ] * ... * A [ n ]

容易看到

S [ i ] = S [ i-1 ] * A [ i-1 ]
T [ i ] = T [ i + 1 ]  * A [ i+1 ]

构造这两个数组所化的时间为o ( 2n )。

其中S是从前往后累乘构造,T是从后往前累乘构造。

之后利用B [ i ] = S [ i ] * T [ i ] ( 2 <= i <= n-1),数组对应的数相乘即可。

实际编码过程中需注意

B [ 1 ] =  T [ 1 ];

B [ n ] =  S [ n ];

可以分别在T数组和S数组的开头和结尾增补一个数据,即S [1] = 1. T[ n ] = 1 

这时,B [ i ] = S [ i ] * T [ i ] ( 1 <= i <= n),

时间复杂度退化为线性,但空间也增至o( 3n )。

以上便是全部解答,希望有帮助!

原文地址:https://www.cnblogs.com/ShaneZhang/p/2171062.html