算法题练习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
复制代码

 

  

 

 

 

 

 

 

posted on   Arts&Crafts  阅读(272)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示