22.<tag-数组和前缀和>-lt.238-除自身以外数组的乘积 1

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

[案例需求]
在这里插入图片描述

[思路分析一, 暴力解法]

  • 由题, 我们可以得出这么一个结论, 那就是每个数nums[i]等于它的前缀乘积 * 后缀乘积
  • 所以我们得出一个很容易想到的解法:
  • 对于原有数组中的每一个数nums[i], 我们借助前缀和写法, 分别使用一个for循环求出nums[i]的前缀之积和后缀之积,分别放在两个数组中
  • 然后再把用一个for循环把这两个数组对应index的求出来即可以得到最终结果数组

[代码实现]

class Solution {
    public int[] productExceptSelf(int[] nums) {
        //每个数等于前一个res*nums[i- 1]/nums[i]
        //前缀的乘积 * 后缀的乘积 = ans
        int len = nums.length;
        // 三轮for循环
         int[] preMulti = new int[len];
         int[] postMulti = new  int[len];

         if(len == 0)return preMulti;
        
         preMulti[0] = 1;
         postMulti[len - 1] = 1;
         for(int i = 1; i < len; i++){
             preMulti[i] = preMulti[i - 1] * nums[ i - 1];
         }

         for(int i = len - 2; i >= 0; i--){
             postMulti[i] = postMulti[i + 1] * nums[i + 1];
         }

         for(int j = 0; j < len; j++){
             preMulti[j] *= postMulti[j];
         }

         return preMulti;
         }
      }

在这里插入图片描述

[思路分析二, 优化解法]

  • 跟思路一基本一致, 只不过是把后缀之积算出来后直接在前缀之积上直接相乘得出结果

[代码实现]

class Solution {
    public int[] productExceptSelf(int[] nums) {
       
        //优化, 两轮for循环
        int[] ans = new int[len];
        int R = 1; //用来存储后缀之积, R就是当前数nums[i] 右边的数的连乘之积
        ans[0] = 1;
        //求出前缀之积
        for(int i = 1; i < len; i++){
            ans[i] = ans[i - 1] * nums[i - 1];
        }

        //求出答案
        //倒序遍历, 因为初始nums[i]为最后一个数, 所以他右边的乘积为1 R=1;
        for(int i = len - 1; i >= 0; i--){
            //
            ans[i] = R * ans[i]; //直接在前缀乘积数组上, 把每个数除了自己的成绩(后缀 * 前缀)重新入到数组
            R = nums[i] * R;// R此时要更改为下一个数(i--)的后缀之积
        }
        return ans;
    }
}

在这里插入图片描述

posted @ 2022-05-26 20:29  青松城  阅读(25)  评论(0)    收藏  举报