力扣面试经典算法150题:除自身以外数组的乘积

除自身以外数组的乘积算法详解

今天的题目是力扣面试经典150题中的数组的中等难度题:除自身以外数组的乘积。

题目链接:https://leetcode.cn/problems/product-of-array-except-self/description/?envType=study-plan-v2&envId=top-interview-150

问题描述

给你一个整数数组 nums,返回 数组 answer ,其中 answeri 等于 nums 中除 numsi 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

请不要使用除法,且在 O(n) 时间复杂度内完成此题。

  • 示例 1:

    • 输入:

      nums = 1,2,3,4

    • 输出:

      24,12,8,6

    • 解释: 对于每个位置 i,outputi 是 nums 中除 numsi 以外所有元素的乘积。

  • 示例 2:

    • 输入:

      nums = -1,1,0,-3,3

    • 输出:

      0,0,9,0,0

    • 解释: 对于每个位置 i,outputi 是 nums 中除 numsi 以外所有元素的乘积。

题目分析

先看题目要求,给定数组,输出一个数组,并且这个数组的每个元素的值,是给定数组除当前位置外所有元素的乘积。

我们再看示例,也很明显:

  • 24 = 2x3x4
  • 12 = 1x3x4
  • 8 = 1x2x4
  • 6 = 1x2x3
  • 0 = 1x0x-3x3
  • 0 = -1x0x-1x3
  • 9 = -1x1x-3x3
  • 0 = -1x1x0x3
  • 0 = -1x1x0x-3

那么,对题目要求我们已经明确了,再看题目其他信息:请不要使用除法,且在 O(n) 时间复杂度内完成此题。

正常情况下,这种求除自身元素外乘积的题目,直接所有元素相乘再除自身就能得到答案(求和,差,商类似),但是题目要求我们不能用除法,所以这个解法直接排除。

在 O(n) 时间复杂度内完成此题,这句话就明确了,我们解答题目,最多只能一层for循环,这样才能保证时间复杂度在O(n),但是题目没有要求空间复杂度,所以我们考虑用多个数组来实现解题。

解题思路

题目要求新数组元素的值是除自身外的所有元素的乘积,是不是可以理解为 元素左边的所有元素的乘积与元素右边所有元素的乘积再相乘呢?另外,由于首个位置的元素和最后位置的元素缺失一边的元素乘积,为了不影响结果,我们可以设定缺失的那边值为1。

由此,我们针对示例的分析可以修改如下:

  • 24 = 1(假定的左边乘积) x (2x3x4)(右边的乘积)
  • 12 = 1(左边的乘积)x(3x4)(右边的乘积)
  • 8 = (1x2)(左边的乘积)x4(右边的乘积)
  • 6 = (1x2x3)(左边的乘积)x1(假定的右边乘积)

另外在分析的时候,我们已经考虑了用多个数组实现解题,因为多个数组分多次循环,不改变时间复杂度为O(n),只是影响空间复杂度。

所以我们可以直接设定两个数组,一个数组计算元素左边的乘积,一个元素计算右边的乘积,最后相乘,即可得到答案。

当然,实际计算的时候,我们在计算第二个数组的乘积的时候,将第一个数组的乘积相乘即可。

实际算法代码

以下是使用上述思路的 Java 实现:

java 复制代码
public class ProductExceptSelf {
   public static void main(String[] args) {
        ProductExceptSelf solution = new ProductExceptSelf();
        int[] nums1 = {1, 2, 3, 4};
        int[] result1 = solution.productExceptSelf(nums1);
        System.out.println(Arrays.toString(result1)); // 输出: [24, 12, 8, 6]

        int[] nums2 = {-1, 1, 0, -3, 3};
        int[] result2 = solution.productExceptSelf(nums2);
        System.out.println(Arrays.toString(result2)); // 输出: [0, 0, 9, 0, 0]
    }

    public int[] productExceptSelf(int[] nums) {
        int length = nums.length;
        int[] answer = new int[length];

        // 从左向右计算左侧所有元素的乘积
        answer[0] = 1;
        for (int i = 1; i < length; i++) {
            answer[i] = nums[i - 1] * answer[i - 1];
        }

        // 从右向左计算右侧所有元素的乘积
        int R = 1;
        for (int i = length - 1; i >= 0; i--) {
            answer[i] = answer[i] * R;
            R *= nums[i];
        }

        return answer;
    }
}

结果

运行代码,结果符合:

提交到力扣,也通过测试:

总结

通过两个数组的方式,我们分别对左右相乘,再将最终结果相乘,成功得到答案,类似的和,差,商的题目一样的解法。做这些题目,一定要归纳总结出一些自己的东西,而不是盲目的解题,看解析。

加油!!!

相关推荐
aqiu1111111 分钟前
python02
算法
折哥的程序人生 · 物流技术专研1 分钟前
《Java 100 天进阶之路》第93篇:Redis实战应用:缓存策略与分布式锁(2026版)
java·redis·缓存·面试·架构·求职招聘
瓦特what?2 分钟前
位运算核心技巧与应用
java·jvm·算法
无限码力2 分钟前
阿里算法岗 0530笔试真题 - 荆棘林的最优砍断计划
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试真题·阿里巴巴笔试真题
人道领域4 分钟前
【LeetCode刷题日记】90.子集Ⅱ--- 归纳题解
java·开发语言·leetcode
随意起个昵称4 分钟前
线性dp-LIS题目5(导弹拦截,二分优化)
c++·算法·动态规划
winlife_5 分钟前
全程用 AI 做一款商业级手游 · EP10 道具系统:让三个按钮真正改变棋盘
windows·算法·unity·ai编程·游戏开发·mcp·玩法系统
计算机安禾8 分钟前
【数据库系统原理】第16篇:范式理论(下):多值依赖与第四范式——消除非平凡的非函数依赖
算法
ch.ju10 分钟前
Java Programming Chapter 4——Characteristics of inheritance
java·开发语言
就叫_这个吧12 分钟前
tomcat在idea控制台乱码问题解决
java·tomcat·intellij-idea