您现在的位置是:首页 >技术教程 >LeetCode: 238. 除自身以外数组的乘积网站首页技术教程

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

姬如祎 2024-08-29 00:01:02
简介LeetCode: 238. 除自身以外数组的乘积

目录

1. 解法一:时:O(N) ,空:O(N)

2. 解法二:(解法一的空间优化) 时:O(N),空:O(1)

 3. 解法三


原题链接:238. 除自身以外数组的乘积 - 力扣(Leetcode)

题目描述:

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

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

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

 注意:就算能使用除法,要是数组中出现0,该方法同样会失效。(求出整个数组的乘积,分别除以数组中的每一位) 

1. 解法一:时:O(N) ,空:O(N)

构造一个类似前缀和一样的数组,只不过是前缀的积,不妨把他记为 L 数组。不仅如此还需要对后缀数组进行同样的操作,不妨记为 R 数组。其中 L 数组下标为 i 的值表示原数组下标从 [0, i - 1] 的元素乘积,R 数组下标为 i 的值表示原数组下标从 [i + 1, 原数组大小 - 1] 的元素乘积。

对于 L 数组下标为 0 的位置,[ 0, -1 ] 显然不存在,即下标为 0 的位置没有左侧的元素,初始化为1 即可。R 数组同理

然后将相同位置下标的 L 数组的值与 R 数组的值相乘即是该下标对应的最终结果。

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int length = nums.size();
        vector<int> L(length);
        vector<int> R(length);
        L[0] = 1;
        for(int i = 1; i < length; i++)
            L[i] = L[i - 1] * nums[i - 1];

        R[length - 1] = 1;
        for(int i = length - 2; i >= 0; i--)
            R[i] = R[i + 1] * nums[i + 1];

        vector<int> answer(length);
        for(int i = 0; i < length; i++)
            answer[i] = L[i] * R[i];
        return answer;
    }

};

2. 解法二:(解法一的空间优化) 时:O(N),空:O(1)

返回的数组不计入空间复杂度的计算,我们可以用返回的数组来存解法一的 L 数组,或者 R 数组,然后反向遍历,用一个变量存储另一侧数组元素的乘积即可。

如果返回结果的数组存 L 数组,那么从后往前遍历,用一个变量存储遍历下标的右侧元素的乘积即可。

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int length = nums.size();
        int left = 1, right = 1;
        vector<int> answer(length, 1);
        for(int i = 0; i < length; i++)
        {
            answer[i] *= left;
            left *= nums[i];

            answer[length - 1 - i] *= right;
            right *= nums[length - 1 - i];
        }
        return answer;
    }

};

 3. 解法三

既然可以用一个变量来计算一侧元素的乘积,那么用两个变量来计算两侧元素的乘积当然也是可行的。维护两个变量,left 用来计算左侧元素的乘积,right用来计算右侧元素的乘积。在遍历的过程中实时更新 left 和 right 即可。

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int length = nums.size();
        vector<int> answer(length);

        answer[0] = 1;
        for(int i = 1; i < length; i++)
            answer[i] = answer[i - 1] * nums[i - 1];

        int right = 1;
        for(int i = length - 1; i >= 0; i--)
        {
            answer[i] = answer[i] * right;
            right *= nums[i];
        }
        return answer;
    }

};

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。