Java算法-力扣leetcode-238. 除自身以外数组的乘积

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)假如可以使用除法
  • 先遍历一遍求出总乘积
  • 遍历到某一位时,总乘积除以当前元素.

问题: 如果其中存在0怎么办, 如果等于0的元素大于1 那么所有结果都是0, 如果只有一个元素等于0,那么单独求下这个元素的左右乘积.其余结果都是0.

解(2)使用两个数组分别保存左右乘积结果.
复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        //left[i]存放i位置的左乘机
        int left[] = new int[nums.length];
        
        //right[i]存放i位置的右乘机
        int right[] = new int[nums.length];
        
        //存放结果
        int answer[] = new int[nums.length];
        
        //边界初始值都为一
        left[0] = 1;
        
        //边界初始值都为一
        right[nums.length - 1] = 1;

        //从左往右遍历
        for (int i = 1; i < nums.length; i++) {
            left[i] = left[i - 1] * nums[i - 1];
        }

        //从右往左遍历
        for (int i = nums.length - 2; i >= 0; i--) {
            right[i] = right[i + 1] * nums[i + 1];
        }
        
        //求结果
        for (int i = 0; i < nums.length; i++) {
            answer[i] = left[i] * right[i];
        }
        return answer;

    }
}
解(3)题目要求尽量节约额外空间
  • 我们可以用最终返回的数组暂时存储左边的乘积

  • 用一个变量从右往左的遍历中记录右边的累积乘积

  • 从右往左的遍历依次根据左边的乘积相乘记录的右乘积更新结果数组

    class Solution {
    public int[] productExceptSelf(int[] nums) {

    复制代码
          int answer[] = new int[nums.length];
          answer[0] = 1;
    
          for (int i = 1; i < answer.length; i++) {
              answer[i] = answer[i - 1] * nums[i - 1];
          }
          int right = 1;
          for (int i = nums.length - 2; i >= 0; i--) {
              right = right * nums[i + 1];
              answer[i] = right * answer[i];
          }
    
          return answer;
    
      }

    }

解(4)尽量减少for循环
  • 题解3中先从左往右变量、再从右往左遍历.

  • 最终结果是左遍历的乘积 乘以 右边遍历的乘积

  • 但是左右的乘积没有依赖关系, 也就是说可以同时左右一起计算.

    class Solution {
    public int[] productExceptSelf(int[] nums) {

    复制代码
          int answer[] = new int[nums.length];
          
          //头左乘积为1
          answer[0] = 1;
          
          //尾右乘积为1
          answer[nums.length - 1 ] = 1;
          
          //头指针 尾指针遍历
          for(int i=1, j=nums.length-2,  left=1,  right=1; i<nums.length; i++,j--){
               //计算左累积乘积
               left = left * nums[i-1];
               
               //计算右累积乘积
               right = right * nums[j+1];
               
              //下边几个判断主要为了判断左右遍历到哪个位置了
              
              //左右还没交叉 各自保存各自的左右乘积
              if(i<j){
                  answer[i] = left;
                  answer[j] = right;
              }
              
              //刚好交叉 左右乘积乘一起
              if(i==j){
                  answer[i] = left*right;
              }
              
              //已经超过了, 左右乘积乘一起
              if(i>j){
                  answer[i] = left * answer[i];
                  answer[j] = right * answer[j];
              }
          }
    
    
          return answer;
    
      }

    }

上面if(i==j) if(i<j) if(i>j)主要是因为int数组默认是0.不能直接全部都乘起来. 可以使用Arrays.fill(answer,1); 将数组填充1 就不用这么多判断了。但是需要增加一次遍历.

相关推荐
做一位快乐的码农29 分钟前
基于springboot的在线考试系统/考试信息管理平台
java·struts·spring·eclipse·tomcat·maven·hibernate
创码小奇客34 分钟前
Spring Boot 集成 Talos:打造智能调参系统,让模型性能自动飙升
java·spring boot·trae
xiaobaibai15338 分钟前
智慧交通中目标检测 mAP↑28%:陌讯多模态融合算法实战解析
人工智能·算法·目标检测·计算机视觉·目标跟踪·视觉检测
战争热诚1 小时前
基于transformer的目标检测——匈牙利匹配算法
算法·目标检测·transformer
计算机科研圈1 小时前
ICCV 2025 | EPD-Solver:西湖大学发布并行加速扩散采样算法
人工智能·算法·语言模型·自然语言处理·数据挖掘·iccv
Yzxs0091 小时前
【8月优质EI会议合集|高录用|EI检索稳定】计算机、光学、通信技术、电子、建模、数学、通信工程...
大数据·人工智能·算法·计算机视觉·信息与通信
探索java1 小时前
Spring lookup-method实现原理深度解析
java·后端·spring
lxsy2 小时前
spring-ai-alibaba 之 graph 槽点
java·后端·spring·吐槽·ai-alibaba
梦幻通灵2 小时前
IDEA查看源码利器XCodeMap插件
java·intellij-idea
Ashlee_code2 小时前
南太平洋金融基建革命:斐济-巴新交易所联盟的技术破局之路 ——从关税动荡到离岸红利,跨境科技如何重塑太平洋资本生态
java·开发语言·科技·金融·重构·web3·php