剑指 Offer 66. 构建乘积数组-双向前缀和

1.题目

2.思路

这个题的唯一限制为不能使用除法!!!--如果可以使用除法,直接计算所有的成绩mul 除以 a[i]就可以了,显然没有这么简单。

然后看这个题需要计算多个数乘在一起,很容易想到前缀和的思想,这里应用为前缀积,可以直接计算a[i]前半部分的乘积a[0] * a[1] * a[2] * ...*a[i-1],然后发现还少后半部乘积,自己卡住了,10分钟...........

一看答案,再反向前缀积就好了。。。a[n- 1] * a[n -2] * ...* a[i +1]

前缀和 ---遍历三次--O(N) - 2ms

class Solution {
    public int[] constructArr(int[] a) {
        int n = a.length;
        if(n == 0) return new int[]{};
        int[]ans = new int[n];
        long[]preMul = new long[n + 1];
        preMul[0] = 1;
        for(int i = 1 ; i <= n; i++){
            // 从前往后计算
            preMul[i] = preMul[i - 1] * a[i - 1]; 
            // System.out.println(preMul[i]);
            // 等于 0 怎么办
        }

        long[]backMul = new long[n + 1];
        backMul[0] = 1;
        for(int i = 1; i <= n ; i++){
            backMul[i] = backMul[i - 1] * a[n - i]; //从后往前计算 
            // System.out.println(backMul[i]+">>>");
        }
        for(int i = 0 ; i < n; i++){
            long t1 = 1;
            if(i != 0) t1 = preMul[i];

            long t2 = 1;
            if(i != n - 1) t2 = backMul[n - i - 1];
            ans[i] = (int)(t1 * t2);
        }
        return ans;
    }
}

 前缀和 ---遍历两次--O(N) - 1ms【还可以只遍历一次就解决的】

class Solution {
    public int[] constructArr(int[] a) {
        int n = a.length;
        if(n == 0) return new int[]{};
        int[]ans = new int[n];
        long[]preMul = new long[n + 1];
        preMul[0] = 1;
        // for(int i = 1 ; i <= n; i++){
        //     // 从前往后计算
        //     preMul[i] = preMul[i - 1] * a[i - 1]; 
        //     // System.out.println(preMul[i]);
        //     // 等于 0 怎么办
        // }

        int[]backMul = new int[n + 1];
        backMul[0] = 1;
        for(int i = 1; i <= n ; i++){
            backMul[i] = backMul[i - 1] * a[n - i]; //从后往前计算 
            // System.out.println(backMul[i]+">>>");
        }
        int t1 = 1;
        for(int i = 0 ; i < n; i++){
            int t2 = 1;
            if(i != 0) t1 *= a[i - 1];
            if(i != n - 1) t2 = backMul[n - i - 1];
            ans[i] = t1 * t2;
        }
        return ans;
    }
}

3.结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值