剑指offer 面试题66. 构建乘积数组(易)
考查应聘者的发散思维能力。这道题目有两种常规解法:一种是把所有数字都相乘再分别除以各个数字,但题目已经限定不能使用除法;另一种解法是连乘 n-1
个数字得到 B[i]
。通常面试官会告知应聘者还有比 \(O(n^2)\) 更高效的算法。此时应聘者不能放弃,还要继续打开思路,多角度去分析解答问题。
Question
给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
示例: 1
2输入: [1,2,3,4,5]
输出: [120,60,40,30,24]a.length <= 100000
测试用例
功能测试(输入数组包含正数、负数、一个0、多个0)。 边界值测试(输入数组的长度为0)。
本题考点
考查应聘者的发散思维能力。这道题目有两种常规解法:一种是把所有数字都相乘再分别除以各个数字,但题目已经限定不能使用除法;另一种解法是连乘 n-1
个数字得到 B[i]
。通常面试官会告知应聘者还有比 \(O(n^2)\) 更高效的算法。此时应聘者不能放弃,还要继续打开思路,多角度去分析解答问题。 考查应聘者对数组的理解和编程能力。
Intuition
可以把 B[i]=A[0]×A[1]…×A[i-1]×A[i+1]…×A[n-1]
看成 A[0]×A[1]…×A[i-1]
和 A[i+1]…×A[n-1]
两部分的乘积。因此,数组 B
可以用一个矩阵来创建。在下图中,B[i]
为矩阵中第i
行所有元素的乘积。

不妨定义C[i]=A[0]×A[1]×…×A[i-2]×A[i-1]
,D[i]=A[i+1]×…×A[n-2]×A[n-1]
。 C[i]
可以用自上而下的顺序计算出来,即 C[i]=C[i-1]×A[i-1]
,其中 C[i-1]=A[0]×A[1]×…×A[i-2]
。类似的 D[i]
,也可以用自下而上的顺序计算出来,即D[i]=D[i+1]×A[i+1]
,其中D[i+1]=A[i+2]×…×A[n-2]×A[n-1]
。
时间复杂度: \(O(N)\) ,其中 \(N\) 为数组长度,两轮遍历数组 \(a\) ,使用 \(O(N)\) 时间。
空间复杂度: \(O(N)\) ,变量 B[]
和 C[]
使用 n
大小额外空间。
Code
- 我的解法
1 |
|
该解法通过不了LeetCode最后的那个超长的 TestCase,说明空间复杂度太大也会通过不了测试用例。
- Krahets大佬解法
1 |
|
时间复杂度: \(O(N)\) ,其中 \(N\) 为数组长度,两轮遍历数组 \(a\) ,使用 \(O(N)\) 时间。
空间复杂度: \(O(1)\) ,变量 tmp
使用常数大小额外空间(数组 b
作为返回值,不计入复杂度考虑)。
作者:Krahets 链接:https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof/solution/mian-shi-ti-66-gou-jian-cheng-ji-shu-zu-biao-ge-fe/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!