LeetCode算法题(Go语言实现)_07

题目

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n) 时间复杂度内完成此题。

一、代码实现

func productExceptSelf(nums []int) []int {
    n := len(nums)
    answer := make([]int, n)
    
    // 计算左侧乘积
    answer[0] = 1
    for i := 1; i < n; i++ {
        answer[i] = answer[i-1] * nums[i-1]
    }
    
    // 计算右侧乘积并合并结果
    right := 1
    for i := n-1; i >= 0; i-- {
        answer[i] *= right
        right *= nums[i]
    }
    
    return answer
}

二、算法分析

1. 核心思路

左右乘积分解:将每个位置的乘积拆分为左侧所有元素的乘积和右侧所有元素的乘积的积。
空间优化:复用输出数组,先存储左侧乘积,再动态计算右侧乘积并直接合并。

2. 关键步骤
  1. 左侧乘积计算:从左到右遍历,将每个位置的左侧乘积存入 answer 数组。
  2. 右侧乘积计算与合并:从右到左遍历,用变量 right 动态累积右侧乘积,并同步更新 answer 数组。
3. 复杂度

时间复杂度O(n),两次独立的线性遍历。
空间复杂度O(1)(不考虑输出数组的空间),仅使用常数额外空间。

三、图解

LeetCode算法题(Go语言实现)_07_第1张图片

四、边界条件与扩展

1. 边界条件

全零数组:如 nums = [0,0,0] → 结果为 [0,0,0]
单个零元素:如 nums = [0,1,2] → 结果为 [2, 0, 0]
数组长度为1:如 nums = [5] → 结果为 [1](无其他元素可乘)。

2. 扩展验证

负数情况:如 nums = [-1, 2, -3] → 结果为 [-6, 3, -2]
大数溢出:题目保证结果在 32 位整数范围内,无需额外处理。

五、总结

核心逻辑:通过左右分解避免重复计算,两次遍历实现高效求解。
优化关键:复用输出数组存储中间结果,空间复杂度从 O(n) 优化至 O(1)
适用场景:类似“利用前后缀信息”的问题(如统计前后缀最大值、求和等)。

你可能感兴趣的:(Golang学习笔记,算法,leetcode,职场和发展,golang)