您的位置首页 >人工智能 >

Rust 实现 LeetCode238 除自身以外数组的乘积题解

LeetCode238 这道题核心解法是前后缀乘积法,在 Rust 里面可以做到 O (n) 时间、O (1) 额外空间,并且全程不能使用除法,完美满足题目的进阶要求,这也是面试里最推荐的写法。这道题不能直接算出总乘积再除以当前元素,因为数组里面可能存在 0,除法会直接报错,题目也明确禁止除法操作。思路就是把每个位置的结果拆成左边所有数字乘积 × 右边所有数字乘积,先从左往右遍历把前缀积写到结果数组,再从右往左遍历,用一个变量维护后缀积,直接乘进结果数组,不需要额外开辟前缀、后缀数组,节省内存,适合数组长度最大 10^5 的大数据场景。

题目要求

  • 输入:整数数组 nums,2 ≤ nums.length ≤ 10^5
  • 输出:answer 数组,answer [i] = nums 中除 nums [i] 之外所有元素乘积
  • 硬性约束:禁止使用除法,时间复杂度 O (n)
  • 进阶:额外空间 O (1)(输出数组不计入额外空间)
  • 保证乘积结果在 32 位 i32 整数范围内

两种 Rust 实现方案

方案 1:O (n) 额外空间(好理解,适合初学)

思路是单独开前缀数组、后缀数组。前缀数组 prefix [i] 代表 i 左边全部元素乘积,后缀数组 suffix [i] 代表 i 右边全部元素乘积,最后结果就是 prefix [i] suffix [i]。

pub fn product_except_self(nums: Vec) -> Vec {

let n = nums.len();

let mut prefix = vec![1; n];

let mut suffix = vec![1; n];

let mut ans = vec![0; n];

for i in 1..n {

prefix[i] = prefix[i - 1] nums[i - 1];

}

for i in (0..n - 1).rev() {

suffix[i] = suffix[i + 1] nums[i + 1];

}

for i in 0..n {

ans[i] = prefix[i] suffix[i];

}

ans

}

方案 2:O (1) 额外空间(最优,推荐提交)

复用 answer 数组存前缀积,只用一个变量保存后缀积,两次遍历完成计算,是 LeetCode 官方推荐写法。

pub fn product_except_self(nums: Vec) -> Vec {

let n = nums.len();

let mut ans = vec![1; n];

let mut prefix = 1;

// 左向遍历,填充前缀积

for i in 0..n {

ans[i] = prefix;

prefix = nums[i];

}

let mut suffix = 1;

// 右向遍历,乘上后缀积

for i in (0..n).rev() {

ans[i] = suffix;

suffix = nums[i];

}

ans

}

测试样例验证

输入数组输出结果说明
[1,2,3,4][24,12,8,6]常规正数数组
[-1,1,0,-3,3][0,0,9,0,0]包含 0 元素

复杂度说明

  • 最优方案时间复杂度:O (n),数组两轮线性遍历
  • 最优方案额外空间复杂度:O (1),只使用 prefix、suffix 两个临时变量
  • 空间方案 1 额外空间复杂度:O (n),前缀、后缀辅助数组

易错点清单

  1. 不要用除法实现,数组存在 0 的时候直接失效,不符合题目限制
  2. Rust 中 i32 溢出不用额外处理,题目保证结果合法
  3. 反向遍历的时候,后缀初始值必须是 1,和前缀逻辑保持一致
  4. 数组长度最小是 2,不用单独处理长度为 1 的边界

【相关 FAQ】

问题 1:Rust 写 LeetCode238 除自身以外数组的乘积,为什么不能直接用总乘积除以当前元素?

回答 1:LeetCode238 题目明确禁止除法,同时数组里面一旦出现 0,总乘积会变成 0,除法运算会出错,Rust 里除以 0 还会直接程序 panic,所以 Rust 实现 LeetCode238 必须用前后缀乘积思路。

问题 2:Rust 版本 LeetCode238 除自身以外数组的乘积 O (1) 空间解法,是怎么节省空间的?

回答 2:Rust 的 LeetCode238 O (1) 解法直接复用输出数组存放前缀乘积,不再单独开辟前缀、后缀数组,只用两个 i32 变量滚动保存前缀、后缀乘积,输出数组不计入额外空间,满足进阶要求。

问题 3:Rust 提交 LeetCode238 除自身以外数组的乘积,遇到负数和 0 的测试用例代码会报错吗?

回答 3:不会,这套 Rust 前后缀乘积代码只做乘法,天然兼容负数、0,LeetCode238 题目保证所有位置最终乘积都落在 i32 范围内,不会触发 Rust 整数溢出 panic。

【参考资料】

[2026-11-08](238. 除自身以外数组的乘积)力扣 LeetCode 题解区

[2026-04-15](LeetCode 238 Product of Array Except Self Rust)JZLeetCode

[2026-04-02](Product of Array Except Self 面试解析)intervu.dev

[2026-01-10](LeetCode 238 前后缀分解思路)NeetCode

【免责声明】

本文为 LeetCode238 Rust 算法题解整理,代码仅用于算法学习、刷题练习;Rust 整数溢出行为受编译模式影响,在线 OJ 默认环境下以题目数据保证为准,不保证在其他自定义场景下稳定运行,不构成工程生产代码直接使用依据。