LeetCode-238 除自身以外数组的乘积
题目来源
题目描述
给你一个长度为 n 的整数数组 nums
,其中 n > 1,返回输出数组 output
,其中 output[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
提示: 题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
题解分析
复杂度O(n)+空间复杂度O(n)解法
解法一
- 从本题的题目可以分析,结果数组中,每一个位置的结果是原始数组前半部分和后半部分的乘积。
- 所以,可以分别增加两个数组分别存储前缀数组和后缀数组的积。
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] pre = new int[n], last = new int[n];
pre[0] = 1;
for(int i = 1; i < n; i++){
pre[i] =pre[i-1] * nums[i-1];
}
last[n-1] = 1;
for(int i = n-2; i >=0; i--){
last[i] = last[i+1] * nums[i+1];
}
int[] result = new int[n];
for(int i = 0; i < n; i++){
result[i] = pre[i] * last[i];
}
return result;
}
}
解法二
- 仔细检查上述代码,可以发现我们的last数组其实是多余的,可以将result数组和last数组混合使用。
- 通过减少一个数组,也减少了内存消耗。
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] pre = new int[n], last = new int[n];
pre[0] = 1;
for(int i = 1; i < n; i++){
pre[i] =pre[i-1] * nums[i-1];
}
last[n-1] = 1;
for(int i = n-2; i >=0; i--){
last[i] = last[i+1] * nums[i+1];
}
for(int i = 0; i < n; i++){
last[i] = pre[i] * last[i];
}
return last;
}
}
时间复杂度O(n)+空间复杂度O(1)解法
- 再仔细查看解法二的算法,其实还可以发现一个更优的解法。
- 因为pre前缀数组是前向遍历的,而且我们的result数组计算也是前向遍历的,那这两个步骤是不是可以结合起来呢?
- 这其实是行得通的,我们可以通过设置一个前缀积变量来累积前缀,在构造result结果数组时,只需要将前缀积变量和last也即result数组相乘即可。
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] result = new int[n];
int pre = 1;
result[n-1] = 1;
for(int i = n-2; i >=0; i--){
result[i] = result[i+1] * nums[i+1];
}
for(int i = 1; i < n; i++){
pre = pre * nums[i-1];
result[i] = pre * result[i];
}
return result;
}
}
Either Excellent or Rusty
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了