hot 100 第十六题 16.除了自身以外数组的乘积

题目:

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除了 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

不要使用除法, 且在 O(n) 时间复杂度内完成此题。

示例 1:

复制代码
输入: nums = [1,2,3,4]
输出: [24,12,8,6]

示例 2:

复制代码
输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]

核心思路

对于每个位置 ,答案 = 左边所有数的乘积 × 右边所有数的乘积 i

!leading-relaxed 复制代码
<span style="color:#eaecf0"><code>nums = [1, 2, 3, 4]

位置0: answer[0] = (左边没有) × (2×3×4) = 1 × 24 = 24
位置1: answer[1] = (1) × (3×4) = 1 × 12 = 12
位置2: answer[2] = (1×2) × (4) = 2 × 4 = 8
位置3: answer[3] = (1×2×3) × (右边没有) = 6 × 1 = 6

结果: [24, 12, 8, 6]</code></span>

两次遍历法

  1. 第一次从左到右,计算每个位置左边的乘积
  2. 第二次从右到左,计算每个位置右边的乘积并累

为什么不用除法?

如果用除法会遇到问题:

复制代码
// 错误思路:总乘积 ÷ 当前元素
int totalProduct = 1;
for (int num : nums) {
    totalProduct *= num;
}
for (int i = 0; i < nums.length; i++) {
    answer[i] = totalProduct / nums[i];  // ✗ 当 nums[i]=0 时会报错
}

问题:

  1. 数组中有 0 会导致除以 0 错误
  2. 题目明确要求不能使用除法

题解:

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] answer = new int[n];
        
        // 第一步:计算左边的乘积
        answer[0] = 1;  // 最左边没有左侧元素,乘积为1
        for (int i = 1; i < n; i++) {
            answer[i] = answer[i - 1] * nums[i - 1];
        }
        
        // 第二步:计算右边的乘积并累乘
        int rightProduct = 1;  // 最右边没有右侧元素,乘积为1
        for (int i = n - 1; i >= 0; i--) {
            answer[i] = answer[i] * rightProduct;
            rightProduct = rightProduct * nums[i];
        }
        
        return answer;
    }
}
```

## 详细演示
```
nums = [1, 2, 3, 4]

第一步:从左到右,计算左边的乘积
answer[0] = 1              (左边没有元素)
answer[1] = 1 × nums[0] = 1 × 1 = 1
answer[2] = 1 × nums[1] = 1 × 2 = 2
answer[3] = 2 × nums[2] = 2 × 3 = 6

此时 answer = [1, 1, 2, 6]
                ↑  ↑  ↑  ↑
               左边的乘积


第二步:从右到左,计算右边的乘积并累乘
rightProduct = 1  (初始值)

i=3: answer[3] = 6 × 1 = 6
     rightProduct = 1 × nums[3] = 1 × 4 = 4

i=2: answer[2] = 2 × 4 = 8
     rightProduct = 4 × nums[2] = 4 × 3 = 12

i=1: answer[1] = 1 × 12 = 12
     rightProduct = 12 × nums[1] = 12 × 2 = 24

i=0: answer[0] = 1 × 24 = 24
     rightProduct = 24 × nums[0] = 24 × 1 = 24

最终 answer = [24, 12, 8, 6]
```

## 图解过程
```
nums = [1, 2, 3, 4]

位置:    0   1   2   3
左乘积:  1   1   2   6   (从左累积: 1, 1×1, 1×2, 2×3)
右乘积: 24  12   4   1   (从右累积: 2×3×4, 3×4, 4, 1)
结果:   24  12   8   6   (左乘积 × 右乘积)

验证:
answer[0] = 1 × 24 = 24 = 2×3×4 ✓
answer[1] = 1 × 12 = 12 = 1×3×4 ✓
answer[2] = 2 × 4 = 8 = 1×2×4 ✓
answer[3] = 6 × 1 = 6 = 1×2×3 ✓
相关推荐
谭欣辰2 分钟前
详细讲解 C++ 有向无环图(DAG)及拓扑排序
c++·算法·图论
承渊政道7 分钟前
【递归、搜索与回溯算法】(掌握记忆化搜索的核心套路)
数据结构·c++·算法·leetcode·macos·动态规划·宽度优先
闻缺陷则喜何志丹9 分钟前
【 线性筛 调和级数】P7281 [COCI 2020/2021 #4] Vepar|普及+
c++·算法·洛谷·线性筛·调和级数
zzzsde11 分钟前
【Linux】线程概念与控制(1)线程基础与分页式存储管理
linux·运维·服务器·开发语言·算法
穿条秋裤到处跑12 分钟前
每日一道leetcode(2026.04.23):等值距离和
算法·leetcode·职场和发展
少许极端16 分钟前
算法奇妙屋(四十九)-贡献法
java·算法·leetcode·贡献法
武帝为此20 分钟前
【特征选择方法】
算法·数学建模
Little At Air23 分钟前
C++priority_queue模拟实现
开发语言·数据结构·c++
XS03010627 分钟前
Agent 记忆管理
大数据·人工智能·算法
探物 AI28 分钟前
【感知·算法】一文综述医学图像分割:从经典 U-Net 到 Mamba 的范式跃迁
算法