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

力扣hot100:除自身以外数组的乘积(除法思路和左右前缀乘积)(238)

大二课程反而更多了,前两天都没怎么学,这几天补上
题目描述

初始思路:利用除法(不符合题目要求)

我最初的想法是先计算所有非零元素的乘积,再根据数组中零的个数分情况处理:

  1. 统计零的个数 遍历数组,计算非零元素的乘积 sum,并统计零的个数 zero_count

  2. 分情况处理

    • 零的个数 > 1:所有结果均为 0。
    • 零的个数 = 1:只有零元素的位置结果为 sum,其余为 0。
    • 没有零:每个位置的结果为 总乘积 / 当前元素
public class productExceptSelf {public int[] productExceptSelf(int[] nums) {int sum=1;int[] result=new int[nums.length];int zero_count=0;for(int i=0;i<nums.length;i++){if(nums[i]!=0) {sum = sum * nums[i];}else{zero_count++;}}if(zero_count>1){for (int i = 0; i < result.length; i++) {result[i]=0;}return result;}if(zero_count==1){for (int i = 0; i < result.length; i++) {if(nums[i]==0){result[i]=sum;}else{result[i]=0;}}return result;} else {for (int i = 0; i < result.length; i++) {if (nums[i] == 0) {result[i] = sum;} else {result[i] = sum / nums[i];}}return result;}}
}

缺陷

  • 题目明确要求不能使用除法,此方案不符合要求。
  • 除法可能导致精度问题(但本题整数数组可接受)。
  • 逻辑分支较多,代码冗余。

优化思路:前缀乘积 + 后缀乘积(完美符合要求)

看了一下官方题解,还是人家名门正统的方法比较合理😂

核心思想:每个位置的结果 = 左侧所有元素的乘积 × 右侧所有元素的乘积

步骤
  1. 计算左侧乘积(从左到右遍历)

    • 初始化 res = 1(第一个元素左侧无元素)。
    • res[i] = res[i-1] * nums[i-1](存储位置 i 左侧所有元素的乘积)。
  2. 计算右侧乘积并更新结果(从右到左遍历)

    • 初始化 right = 1(最后一个元素右侧无元素)。
    • 遍历时,res[i] *= right(左侧乘积 × 右侧乘积)。
    • 更新 right *= nums[i](将当前元素纳入右侧乘积)。
代码实现
public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] res = new int[n];// 计算左侧乘积res[0] = 1;for (int i = 1; i < n; i++) {res[i] = res[i-1] * nums[i-1];}// 计算右侧乘积并更新结果int right = 1;for (int i = n - 1; i >= 0; i--) {res[i] *= right;  // 左侧乘积 × 右侧乘积right *= nums[i]; // 更新右侧乘积}return res;
}

示例分析

nums = [1, 2, 3, 4] 为例:

  1. 左侧乘积计算

    • res = 1
    • res = 1 × 1 = 1
    • res = 1 × 2 = 2
    • res = 2 × 3 = 6
    • 此时 res = [1, 1, 2, 6]
  2. 右侧乘积计算(从右到左):

    • i = 3right = 1 → res = 6 × 1 = 6,更新 right = 1 × 4 = 4
    • i = 2res = 2 × 4 = 8,更新 right = 4 × 3 = 12
    • i = 1res = 1 × 12 = 12,更新 right = 12 × 2 = 24
    • i = 0res = 1 × 24 = 24
    • 最终结果:[24, 12, 8, 6]
复杂度分析
  • 时间复杂度:O(n)O(n),两次遍历数组。
  • 空间复杂度:O(1)O(1)(输出数组不计入)。
优势
  1. 完全避免除法,符合题目要求。
  2. 无需处理零的特殊情况:零在乘法中自动将对应位置结果置零。
  3. 逻辑简洁:仅两次遍历,无复杂分支。

总结

  • 初始方案:依赖除法,需处理零的边界情况,不符合题目要求。
  • 优化方案:通过 前缀乘积 + 后缀乘积 巧妙避免除法,逻辑清晰且高效。 核心技巧:将问题拆分为左右两部分,利用两次遍历累积结果。遇到类似题目时(如前缀和、累积乘积),此思路可举一反三。

最终推荐代码

public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] res = new int[n];res[0] = 1;for (int i = 1; i < n; i++) {res[i] = res[i-1] * nums[i-1];}int right = 1;for (int i = n-1; i >= 0; i--) {res[i] *= right;right *= nums[i];}return res;
}

http://www.xdnf.cn/news/19638.html

相关文章:

  • 毕业项目推荐:70-基于yolov8/yolov5/yolo11的苹果成熟度检测识别系统(Python+卷积神经网络)
  • 【无人机三维路径规划】基于遗传算法GA结合粒子群算法PSO无人机复杂环境避障三维路径规划(含GA和PSO对比)研究
  • 基于单片机醉酒驾驶检测系统/酒精检测/防疲劳驾驶设计
  • 基于单片机雏鸡孵化恒温系统/孵化环境检测系统设计
  • WPF启动窗体的三种方式
  • 【Day 42】Shell-expect和sed
  • 【python】lambda函数
  • Ubuntu 24.04 服务器配置MySQL 8.0.42 三节点集群(一主两从架构)安装部署配置教程
  • ubuntu部署MySQL服务
  • 数据结构——树(04二叉树,二叉搜索树专项,代码练习)
  • 【硬核干货】把 DolphinScheduler 搬进 K8s:奇虎 360 商业化 900 天踩坑全记录
  • 从零开始:用代码解析区块链的核心工作原理
  • linux开发板(rk3568,树莓派)自动连接保存好的WIFI
  • 模板商城探秘:DINO-X 定制模板指南(2)
  • Stop-Process : 由于以下错误而无法停止进程“redis-server (26392)”: 拒绝访问。
  • HTTPS如何保证数据传输过程中的安全性?
  • HQX SELinux 权限问题分析与解决
  • 2025 年,这些求职技能利用空闲时间就能学,轻松提升职场竞争力​
  • 亚马逊的领导力原则
  • Photoshop - Ps 处理图层
  • Qt模型/视图编程详解:QStringListModel与多视图数据同步
  • linux 命令 awk的常见用法
  • Zynq中级开发七项必修课-第四课:S_AXI_HP0 高速端口访问 DDR
  • OCR 识别准确率的关键影响因素
  • NAT与内网穿透
  • 【python】python进阶——pip命令
  • 【完整源码+数据集+部署教程】粘土石实例分割系统源码和数据集:改进yolo11-LVMB
  • Qt Demo(3) 之 deepseek 帮我写的关于图像显示的小界面
  • 【Vue2 ✨】Vue2 入门之旅(十):Vuex 入门
  • 精读:《VideoMAE V2: Scaling Video Masked Autoencoders with Dual Masking》