剑指 Offer 66. 构建乘积数组
一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第27天,点击查看活动详情。
1、题目📑
给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法
实例1:
输入: [1,2,3,4,5]
输出: [120,60,40,30,24]
提示:
- 所有元素乘积之和不会溢出 32 位整数
a.length <= 100000
2、思路🧠
方法一:左侧乘积 ✖ 右侧乘积
可能有小伙伴没有理解题目的意思,这里我简单解释一下,B[i] = 去除A[i] 其余A数组中的数的乘积,也就是说前面的乘积 ✖ 后面的乘积,因此只需要统计出当前这个点左半边的乘积与右半边的乘积。
分析题目主要存在3种情况
- 构建左侧乘积
- 构建右侧乘积
- 对应位置左右乘积进行相乘
构建过程:
-
构建左侧乘积数组
int[] left = new int[a.length]; int temp = 1; for (int i = 0; i < a.length; i++) { left[i] = p; p *= a[i]; } -
构建右侧乘积数组
int[] right = new int[a.length]; temp = 1; for (int i = a.length - 1; i >= 0; i--) { right[i] = p; p *= a[i]; } -
对应位置左右乘积进行相乘
int[] res = new int[a.length]; for (int i = 0; i < a.length; i++) { res[i] = left[i] * right[i]; } return ans;
废话少说~~~~~上代码!
3、代码👨💻
第一次commit AC
class Solution {
public int[] constructArr(int[] a) {
int b [] = new int [a.length];
int res = 1;
for(int i = 0; i < a.length; i++) {
b[i] = res;
res *= a[i];
}
res = 1;
for(int i = a.length - 1; i>= 0; i--) {
b[i] *= res;
res *= a[i];
}
return b;
}
}
时间复杂度:O(N) 其中 N 为数组长度,两轮遍历数组 a ,使用 O(N) 时间。
空间复杂度:O(1)
4、总结
该题目的难点在于 不能使用除法 ,即需要 只用乘法 生成数组 B 。还有一个问题在于如果输入数组中出现 0,那么 先计算给定数组所有元素的乘积,然后对数组中的每个元素 x,将总的乘积除以 x 来求得除自身值的以外数组的乘积 失效了。而且在问题中说明了不允许使用除法运算。这增加了这个问题的难度。
❤️来自专栏《LeetCode基础算法题》欢迎订阅❤️
厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。
对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!