目录
1,题目
2,代码
2.1左右乘积列表
2.2优化-空间复杂度常量化
算法实现:
3,学习与总结
3.1记录我的思考过程
3.2本题特点
1,题目
给你一个整数数组 nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。
题目数据 保证 数组 nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n)
时间复杂度内完成此题。
2,代码
2.1左右乘积列表
维护给定索引处的数字相对应的前缀和后缀;重点在于理解两个列表的初始化过程;
前缀:给定索引左侧所有数字的乘积;
后缀:给定索引右侧所有数字的乘积;
小tips:乘积 利用‘1’;
/**
* @param {number[]} nums
* @return {number[]}
*/
var productExceptSelf = function(nums) {
const n = nums.length;
let ltable = new Array(n).fill(1);
let rtable = new Array(n).fill(1);
let ans = new Array(n).fill(0);
for(let i = 1;i < n;i++){
ltable[i] = ltable[i-1]*nums[i-1];
}
for(let i = n-2; i >= 0;i--){
rtable[i] = rtable[i+1]*nums[i+1];
}
for(let i = 0;i < n;i++){
ans[i] = ltable[i]*rtable[i];
}
return ans;
};
2.2优化-空间复杂度常量化
由于输出数组不算在空间复杂度内,那么我们可以将
L
或R
数组用输出数组来计算。先把输出数组当作L
数组来计算,然后再动态构造R
数组得到结果。
/**
* @param {number[]} nums
* @return {number[]}
*/
var productExceptSelf = function(nums) {
const n = nums.length;
let ans = new Array(n).fill(1);
for(let i = 1;i < n;i++){
ans[i] = ans[i-1]*nums[i-1];
}
// R索引右侧所有数字的乘积
let R = 1;
for(let i = n-1; i >= 0;i--){
ans[i] = ans[i] * R;
R *= nums[i];
}
return ans;
};
算法实现:
- 初始化 ans数组,answer[i] 先代表的是 i 左侧所有数字的乘积。
- 用一个遍历来跟踪右边元素的乘积。并更新数组answer[i]=answer[i]∗R。
说明:
R 更新为 R=R∗nums[i]
变量 R表示的就是索引右侧数字的乘积。
3,学习与总结
3.1记录我的思考过程
(1)积累一下对数组中0个数的统计
const str = nums.join('');
const n = (str.split('0')).length-1;
(2)我的思路
算出数组中所有数字的乘积,除以相对应索引值;
首先,判断0的个数numsOfzero
numsOfzero >= 2
numsOfzero === 1
numsOfzero === 0
问题在于numsOfzero 等于1或者0的情况需要单独处理,整体代码的实现相对繁琐;
3.2本题特点
要学习处理的方法;
了解处理思路后,可以自己实现代码逻辑,即主要在于解题思路上;
勉励自己:贵在坚持!