当前位置: 首页 > news >正文

【LeetCode】238. 除自身以外数组的乘积

除自身以外数组的乘积

题目描述:

        给你一个整数数组 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]

提示:

  • 2 <= nums.length <= 105
  • -30 <= nums[i] <= 30
  • 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在  32 位 整数范围内

进阶:你可以在 O(1) 的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)

方法一思路分析:

  1. 初始化左右乘积数组
    • 创建两个辅助数组 L 和 R,长度与输入数组 nums 相同。L[i] 用于存储 nums[i] 左侧所有元素的乘积,R[i] 用于存储 nums[i] 右侧所有元素的乘积。
  2. 计算左侧乘积
    • 初始化 L[0] 为 1,因为第一个元素左侧没有元素。
    • 从左到右遍历 nums,计算每个位置的左侧乘积并存储在 L 数组中。
  3. 计算右侧乘积
    • 初始化 R[length - 1] 为 1,因为最后一个元素右侧没有元素。
    • 从右到左遍历 nums,计算每个位置的右侧乘积并存储在 R 数组中。
  4. 计算最终结果
    • 创建一个结果数组 answer,长度为 nums 的长度。
    • 对于 nums 中的每个元素,其除了自身以外所有元素的乘积就是其左侧所有元素的乘积乘以右侧所有元素的乘积。即 answer[i] = L[i] * R[i]
  5. 返回结果
    • 返回 answer 数组作为最终结果。

代码实现:

class Solution {public int[] productExceptSelf(int[] nums) {int length = nums.length;// L 和 R 分别表示左右两侧的乘积列表int[] L = new int[length];int[] R = new int[length];int[] answer = new int[length];// L[i] 为索引 i 左侧所有元素的乘积// 对于索引为 '0' 的元素,因为左侧没有元素,所以 L[0] = 1L[0] = 1;for (int i = 1; i < length; i++) {L[i] = nums[i - 1] * L[i - 1];}// R[i] 为索引 i 右侧所有元素的乘积// 对于索引为 'length-1' 的元素,因为右侧没有元素,所以 R[length-1] = 1R[length - 1] = 1;for (int i = length - 2; i >= 0; i--) {R[i] = nums[i + 1] * R[i + 1];}// 对于索引 i,除 nums[i] 之外其余各元素的乘积就是左侧所有元素的乘积乘以右侧所有元素的乘积for (int i = 0; i < length; i++) {answer[i] = L[i] * R[i];}return answer;}
}

方法二思路分析:

        题目进阶要求在 O(1) 的额外空间复杂度内完成这个题目,且输出数组不算额外空间。所以可以考虑用一个变量代替数组的使用,变量为右侧所有元素的乘积。

  1. 计算每个元素左侧所有元素的乘积
    • 创建一个与原数组相同长度的新数组 answer,用于存储结果。
    • 初始化 answer[0] 为 1,因为第一个元素左侧没有其他元素。
    • 从第二个元素开始遍历原数组,每个位置 i 的 answer[i] 等于 nums[i - 1] 乘以 answer[i - 1]。这样,answer[i] 就存储了原数组中索引 i 左侧所有元素的乘积。
  2. 计算每个元素右侧所有元素的乘积,并更新结果数组
    • 初始化一个变量 R 为 1,用于存储当前元素右侧所有元素的乘积。
    • 从原数组的最后一个元素开始向左遍历。
    • 对于每个元素,将其左侧乘积(即 answer[i])与右侧乘积 R 相乘,得到的结果就是除了 nums[i] 以外的所有元素的乘积,并更新 answer[i]
    • 更新 R,将其乘以当前遍历到的元素 nums[i],以便计算下一个元素的右侧乘积。

举一个具体的例子来说明:

假设我们有一个整数数组 nums = [1, 2, 3, 4]

  1. 计算每个元素左侧所有元素的乘积

    • 初始化结果数组 answer = [0, 0, 0, 0]
    • answer[0] 设置为 1,因为第一个元素左侧没有其他元素。
    • 计算 answer[1]answer[1] = nums[0] * answer[0] = 1 * 1 = 1
    • 计算 answer[2]answer[2] = nums[1] * answer[1] = 2 * 1 = 2
    • 计算 answer[3]answer[3] = nums[2] * answer[2] = 3 * 2 = 6

    此时,answer = [1, 1, 2, 6]。这个数组存储了每个元素左侧所有元素的乘积。

  2. 计算每个元素右侧所有元素的乘积,并更新结果数组

    • 初始化变量 R = 1,用于存储当前元素右侧所有元素的乘积。
    • 从右向左遍历 nums 数组。
    • 对于 nums[3](即 4):answer[3] = answer[3] * R = 6 * 1 = 6,然后 R = R * nums[3] = 1 * 4 = 4
    • 对于 nums[2](即 3):answer[2] = answer[2] * R = 2 * 4 = 8,然后 R = R * nums[2] = 4 * 3 = 12
    • 对于 nums[1](即 2):answer[1] = answer[1] * R = 1 * 12 = 12,然后 R = R * nums[1] = 12 * 2 = 24
    • 对于 nums[0](即 1):answer[0] = answer[0] * R = 1 * 24 = 24

    最终,answer = [24, 12, 8, 6]。这个数组就是除了自身以外所有元素的乘积。

代码实现:

class Solution {public int[] productExceptSelf(int[] nums) {int length = nums.length;int[] answer = new int[length];// answer[i] 表示索引 i 左侧所有元素的乘积// 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1answer[0] = 1;for (int i = 1; i < length; i++) {answer[i] = nums[i - 1] * answer[i - 1];}// R 为右侧所有元素的乘积// 刚开始右边没有元素,所以 R = 1int R = 1;for (int i = length - 1; i >= 0; i--) {// 对于索引 i,左边的乘积为 answer[i],右边的乘积为 Ranswer[i] = answer[i] * R;// R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上R *= nums[i];}return answer;}
}

http://www.lryc.cn/news/416710.html

相关文章:

  • Excel公式与函数(运算符,计算限制,错误检查)(一)
  • 用AI助手写程序
  • 动手学深度学习7.2 使用块的网络(VGG)-笔记练习(PyTorch)
  • SolidityFoundry ERC4626
  • 大模型时代的操作系统:融合 Rust 和大模型,打造 AI 操作系统
  • 【ML】为什么要做batch normlization,怎么做batch normlization
  • 【C++指南】命名空间
  • RocketMQ Dashboard安装
  • 前端web开发HTML+CSS3+移动web(0基础,超详细)——第3天
  • 认识MySQL
  • 尚品汇-创建ES索引库(二十七)
  • 设计模式-六大原则
  • MyBatis搭建和增删改查
  • 【一图学技术】6.反向代理 vs API网关 vs 负载均衡的原理和使用场景
  • python爬虫番外篇 | Reuqests库高级用法(1)
  • 【链表OJ】常见面试题 3
  • Linux学习笔记9(Linux包管理)
  • 论文阅读《Geometric deep learning of RNA structure》
  • 宏集方案 | 传统建筑智能化改造,迈向物联新时代
  • 如果服务器更改Web端口会减少被攻击的风险吗?
  • vim列编辑模式
  • 如何实现pxe安装部署
  • 机器学习常见模型
  • 【python案例】基于Python 爬虫的房地产数据可视化分析设计与实现
  • 如何在Python中诊断和解决内存溢出问题
  • 什么是爬虫软件?这两个爬虫神器你必须要试试
  • 记录|MVS和VM软件使用记录
  • 算法通关:014_1:用栈实现队列
  • 【C#】Random
  • MongoDB简介及其在Java中的应用