【力扣hot100】238.除自身以外数组的乘积

一、题目

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

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

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



示例 1:

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

示例 2:

输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]

二、思路

一开始根本想不到用什么模板套,后面看了眼标签有前缀和,但忘记怎么套的了就硬着头皮写了,思路就是创建一个前缀积数组和一个后缀积数组,然后就嗯递归计算,最后相乘得到最后的ans

结果写的就很拉,时间复杂度倒也是O(n),但跑的很慢

三、代码

class Solution {
private:
    vector<int> left;
    vector<int> right;
    vector<int> ans;
public:
    void leftplus(int index,vector<int>& nums){
        if(index>nums.size()-2) return;    //终止

        left.push_back(nums[index]*left[index-1]);
        leftplus(index+1,nums);
        return;
    }
    void rightplus(int index,vector<int>& nums){
        if(index<1) return;    //终止
        
        right[index]=nums[index]*right[index+1];
        rightplus(index-1,nums);
        return;
    }
    vector<int> productExceptSelf(vector<int>& nums) {
        left.push_back(nums[0]);    //前缀积数组初始化
        leftplus(1,nums);

        right.assign(nums.size(), 1);   //后缀积数组初始化
        right[nums.size()-1]=nums[nums.size()-1];
        rightplus(nums.size()-2,nums);

        ans.push_back(right[1]);
        for(int i=1;i<nums.size()-1;i++){
            ans.push_back(left[i-1]*right[i+1]);
        }
        ans.push_back(left[left.size()-1]);
        return ans;
    }
};

拿示例1来说就是要算ans[1]的话就用left[1-1]和right[1+1]乘积就行了因为最多乘nums.size()-1个数,所以ans直接取left的末尾和right的开始即可

四、题解

题解:

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> res(n, 1);
        int l = 1;
        for (int i=0; i<n; i++) {   
            res[i] = l;
            l *= nums[i];
        }
        int r = 1;
        for (int i =n-1; i>=0; i--) {
            res[i] *= r;
            r *= nums[i];
        }
        return res;
    }
};

最聪明的做法,先从前往后将数组都按前缀积乘好,再从后往前用后缀积乘

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值