LeetCode 238:除自身以外数组的乘积(Java实现)

文章目录

    • **题目描述**
    • 解决思路
      • 1. 两次遍历法(左右乘积法)
      • 2. 核心思想
    • Java代码实现
    • 复杂度分析
    • 示例说明
      • 步骤分解
    • 注意事项
    • 总结

题目描述

给定一个整数数组 nums,返回一个数组 answer,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。题目要求:

  1. 时间复杂度为 O(n)
  2. 不能使用除法
  3. 空间复杂度为 O(1)(不包含输出数组)

解决思路

由于不能使用除法,直接计算每个位置左右两侧的乘积是一种高效的方法。具体步骤如下:

1. 两次遍历法(左右乘积法)

  • 第一次遍历(左→右):计算每个元素左侧所有元素的乘积,并存储在结果数组 answer 中。
  • 第二次遍历(右→左):维护一个变量 rightProduct,动态计算当前元素右侧所有元素的乘积,并与左侧乘积相乘,得到最终结果。

2. 核心思想

  • 空间优化:直接复用结果数组 answer,避免额外空间。
  • 分治思想:将问题拆解为“左侧乘积”和“右侧乘积”两部分,分别求解后合并。

Java代码实现

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] answer = new int[n];
        
        // 1. 计算左侧乘积(answer[i] = nums[0] * nums[1] * ... * nums[i-1])
        answer[0] = 1; // 第一个元素左侧无元素,初始化为1
        for (int i = 1; i < n; i++) {
            answer[i] = answer[i - 1] * nums[i - 1];
        }
        
        // 2. 计算右侧乘积并合并结果
        int rightProduct = 1; // 最后一个元素右侧无元素,初始化为1
        for (int i = n - 1; i >= 0; i--) {
            answer[i] *= rightProduct; // 左侧乘积 * 右侧乘积
            rightProduct *= nums[i];     // 更新右侧乘积
        }
        
        return answer;
    }
}

复杂度分析

  • 时间复杂度:O(n),两次独立遍历数组。
  • 空间复杂度:O(1),仅使用常量额外空间(输出数组不计入复杂度)。

示例说明

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

步骤分解

  1. 左侧乘积计算

    • answer[0] = 1(左侧无元素)
    • answer[1] = answer[0] * nums[0] = 1 * 1 = 1
    • answer[2] = answer[1] * nums[1] = 1 * 2 = 2
    • answer[3] = answer[2] * nums[2] = 2 * 3 = 6
    • 此时 answer = [1, 1, 2, 6]
  2. 右侧乘积计算与合并

    • 初始化 rightProduct = 1
    • i=3answer[3] *= 16*1=6,更新 rightProduct = 1*4=4
    • i=2answer[2] *= 42*4=8,更新 rightProduct = 4*3=12
    • i=1answer[1] *= 121*12=12,更新 rightProduct = 12*2=24
    • i=0answer[0] *= 241*24=24,更新 rightProduct = 24*1=24
    • 最终结果:answer = [24, 12, 8, 6]

注意事项

  • 边界条件:当输入数组长度为1时,直接返回 [1]
  • 避免溢出:题目未明确说明数据范围,但实际应用中需考虑乘积溢出问题。

总结

通过两次遍历分别计算左右两侧的乘积,既避免了除法,又优化了空间复杂度。该方法适用于需要前后缀计算的场景(如“接雨水”问题)。关键在于分步拆解问题,复用结果数组减少空间占用。

你可能感兴趣的:(坚持刷题,2025,leetcode,java,算法)