【算法】【数组与矩阵模块】不包含本位置的累乘数组值(含不用除法的方法)

目录

  • 前言
  • 问题介绍
  • 解决方案
  • 代码编写
    • java语言版本
    • c语言版本
    • c++语言版本
  • 思考感悟
  • 写在最后

前言

当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批评指正~

在此感谢左大神让我对算法有了新的感悟认识!

问题介绍

原问题
给定一个无序数组arr,循环遍历arr,求不包含arr[i],剩下的数之间的累乘结果
如:arr = [1,2,3]
结果为:[6,3,2]

解决方案

原问题
方法一(除法):
1、遍历arr,求arr的累乘值,过程中计算0的个数和0第一次出现的index,0不参与累乘
2、判断0的个数,如果0的个数大于1,则直接返回0即可
3、如果0的个数为1,则除了0位置以外为累乘结果,其他位置全部为0
4、如果数组中不存在0,则遍历arr,记录累乘积除以arr[i]的值即可
方法二(不使用除法):
1、申请两个数组,l数组合r数组,l[i]代表除了arr[0…i-1]的累乘积,r[i]代表arr[i+1…arr.len]的累乘积
2、直接遍历arr数组,遍历到arr[i]时,res[i] = l[i] * r[i] ,注意边界即可

代码编写

java语言版本

原问题:
方法一:

    /**
     * 二轮测试:可以使用除法的方法
     * @param arr
     * @return
     */
    public static int[] getMultiCp1(int[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }
        // 记录0的个数
        int count0 = 0;
        // 记录如果只有一个零时,零的位置
        int index0 = 0;
        // 累乘之和
        int all = 1;
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 0) {
                count0++;
                index0 = i;
            }else {
                all *= arr[i];
            }
        }
        if (count0 == 1) {
            res[index0] = all;
        }else if (count0 == 0){
            // 没有零
            for (int i = 0; i < arr.length; i++) {
                res[i] = all/arr[i];
            }
        }
        return res;
    }

方法二:

   /**
     * 二轮测试:不使用除法的方法
     * @param arr
     * @return
     */
    public static int[] getMultiCp2(int[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }
        int len = arr.length;
        // 记录到arr[i]时的累乘
        int[] r = new int[len];
        // l[i]代表从arr[i...len-1]的累乘
        int[] l = new int[len];
        r[0] = arr[0];
        l[len-1] = arr[len-1];
        // 填充r和l
        for (int i = 1; i < len; i++) {
            r[i] = r[i-1] * arr[i];
            l[len-i-1] = l[len-i] * arr[len-i-1];
        }
        // 计算结果
        int[] res = new int[len];
        // 两个边界值先写好
        res[0] = arr[0];
        res[len-1] = arr[len-1];
        for (int i = 1; i < res.length-1; i++) {
            res[i] = r[i-1] * l[i+1];
        }
        return res;
    }
    
    public static void main(String[] args) {
        CommonUtils.printArr(getMultiCp2(new int[]{2,3,1,4}));
    }

c语言版本

正在学习中

c++语言版本

正在学习中

思考感悟

第一次想到的是除法,但是其实最后发现不用除法的方式似乎比除法更好写一点,只是边界值的处理需要多加留意一下,比如如果arr[0]时,此时应该如何填写l[i]?我认为l[i]可以写成1即可,这样在后续处理时不需要特殊的逻辑判断。

写在最后

方案和代码仅提供学习和思考使用,切勿随意滥用!如有错误和不合理的地方,务必批评指正~
如果需要git源码可邮件给[email protected]
再次感谢左大神对我算法的指点迷津!

你可能感兴趣的:(阅读随笔,工作技术栈,算法,算法,矩阵,线性代数)