算法题练习1

来自搜狗的一道笔试题

一个长度为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]的积。
程序要求:
要求具有线性复杂度。
不能使用除法运算符。

首先这题最简单的方法:

def change(a):
    sum = 1
    size = len(a)
    for i in range(size):
        sum = sum * a[i]
    for i in range(size):
        a[i] = sum / a[i]

 很遗憾这题要求不能使用除法,没办法互联网公司就喜欢考把简单的问题复杂化。既然不能使用除法,那我们只能改变思路了。不能使用除法,只能借助另外一个数组来实现了。这一题要求的是数组中每个元素的值更新为其他元素的乘积。所以我们使用一个数组,数组中的每个元素保存其他元素相乘的积,又算法要求是线性的,所以不能简单的每个数组中的元素保存其他元素的乘积(因为那样每存储一个乘积就要遍历整个数组),我们知道数组只能遍历一次,所以每个元素保存值的选择只有两种:1保存其遍历过的元素乘积,2保存期遍历过元素的乘积的值和其自身的乘积的(很显然这种不合适).所以就只能选择第一种方式保存乘积。

  我们选择从后遍历,每个数组的元素的值等于其后面所有数组元素的乘积,假设有原来的数组a有6个元素,则数组 b[5] = 1,b[4] = a[5]*b[5],b[3] = b[4]*a[4].....

  这样b数组中每个元素的值为其后面所有元素的乘积,但是它前面的元素的乘积怎么得到呢。此时我们可以从前开始遍历a,用一个值存储前面遍历元素的乘积。

  比如我们已经遍历到数组a的第三个值也就是a[2],我们用一个元素tmp存储前面所遍历的所有元素的乘积即tmp = a[0]*a[1],这样更新a[2]的时候直接用

  a[2] = tmp * b[2]

算法如下:

 1 def change(a):
 2     size = len(a)
 3     b    = [1 for i in range(size)]
 4     for i in range(size - 2, -1, -1):
 5         b[i] = b[i + 1] * a[i + 1]
 6     c = 1
 7     for i in range(size):
 8         tmp = a[i]
 9         a[i] = c * b[i]
10         c = c * tmp

  

原文地址:https://www.cnblogs.com/ArtsCrafts/p/3390277.html