LeetCode-238 除自身以外数组的乘积

题目来源

LeetCode-238 除自身以外数组的乘积

题目描述

给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

输入: [1,2,3,4]
输出: [24,12,8,6]

提示: 题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。

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

进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)

题解分析

复杂度O(n)+空间复杂度O(n)解法

解法一

  1. 从本题的题目可以分析,结果数组中,每一个位置的结果是原始数组前半部分和后半部分的乘积。
  2. 所以,可以分别增加两个数组分别存储前缀数组和后缀数组的积。
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] pre = new int[n], last = new int[n];
        pre[0] = 1;
        for(int i = 1; i < n; i++){
            pre[i] =pre[i-1] * nums[i-1];
        }
        last[n-1] = 1;
        for(int i = n-2; i >=0; i--){
            last[i] = last[i+1] * nums[i+1];
        }
        int[] result = new int[n];
        for(int i = 0; i < n; i++){
            result[i] = pre[i] * last[i];
        }
        return result;
    }
}

解法二

  1. 仔细检查上述代码,可以发现我们的last数组其实是多余的,可以将result数组和last数组混合使用。
  2. 通过减少一个数组,也减少了内存消耗。
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] pre = new int[n], last = new int[n];
        pre[0] = 1;
        for(int i = 1; i < n; i++){
            pre[i] =pre[i-1] * nums[i-1];
        }
        last[n-1] = 1;
        for(int i = n-2; i >=0; i--){
            last[i] = last[i+1] * nums[i+1];
        }
        for(int i = 0; i < n; i++){
            last[i] = pre[i] * last[i];
        }
        return last;
    }
}

时间复杂度O(n)+空间复杂度O(1)解法

  1. 再仔细查看解法二的算法,其实还可以发现一个更优的解法。
  2. 因为pre前缀数组是前向遍历的,而且我们的result数组计算也是前向遍历的,那这两个步骤是不是可以结合起来呢?
  3. 这其实是行得通的,我们可以通过设置一个前缀积变量来累积前缀,在构造result结果数组时,只需要将前缀积变量和last也即result数组相乘即可。
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] result = new int[n];
        int pre = 1;
        result[n-1] = 1;
        for(int i = n-2; i >=0; i--){
            result[i] = result[i+1] * nums[i+1];
        }
        for(int i = 1; i < n; i++){
            pre = pre * nums[i-1];
            result[i] = pre * result[i];
        }
        return result;
    }
}
posted @ 2021-12-20 10:31  Garrett_Wale  阅读(31)  评论(0编辑  收藏  举报