zoukankan      html  css  js  c++  java
  • 剑指Offer_#66_构建乘积数组

    剑指Offer_#66_构建乘积数组

    Contents

    题目

    给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。

    示例:
    输入: [1,2,3,4,5]
    输出: [120,60,40,30,24]

    提示:
    所有元素乘积之和不会溢出 32 位整数
    a.length <= 100000

    思路分析

    用除法的解法

    本题难点在于题目限制不准用除法,如果可以用除法的话,很好解决。

    • 计算A[]中所有元素乘积product
    • 遍历一遍A[]数组,B[i] = product / A[i]

    不用除法的解法

    将每个B[i]的表达式写出来,就是下面表格的样子。

    我们发现可以每一行被1分为左右两个部分,或者说上三角部分和下三角部分。
    我们可以分别计算每一行当中1的左边部分,1的右边部分,然后将两部分相乘,就得到对应的B[i]
    编码技巧: 计算上下三角部分的乘积时,非常容易弄错,最好先在纸上画出上述表格,然后对照着写,不然容易乱。

    解答

    解答1:较直观的写法

    这个代码比较直观,可读性好,但是空间复杂度稍高,借助2个额外的数组。空间复杂度为O(n)。

    class Solution {
        public int[] constructArr(int[] a) {
            int n = a.length;
            if(n == 0) return new int[0];
            int[] up = new int[n];//上三角部分乘积
            int[] down = new int[n];//下三角部分乘积
            //上三角从最下边的1开始迭代
            up[n - 1] = 1;
            //下三角从最上边的1开始迭代
            down[0] = 1;
            //计算上三角部分,由下到上累乘
            for(int i = n - 2;i >= 0;i--){
                up[i] = up[i + 1] * a[i + 1];
            }
            //计算下三角部分,由上到下累乘
            for(int i = 1; i <= n - 1;i++){
                down[i] = down[i - 1] * a[i - 1];
            }
            //最后将上下三角部分逐位对应相乘,得到的新数组就是结果B[0...n-1]
            for(int i = 0;i <= n - 1;i++){
                up[i] *= down[i];
            }
            return up;
        }
    }

    复杂度分析

    时间复杂度: O(n)
    空间复杂度: O(n)

    解答2:优化空间复杂度

    少用了一个数组,可读性稍微差点。因为b是返回值,所以不算在空间复杂度内。

    class Solution {
        public int[] constructArr(int[] a) {
            if(a.length == 0) return new int[0];
            int[] b = new int[a.length];
            b[0] = 1; 
            //将上三角中的数字乘入b[i]
            for(int i = 1; i <= b.length - 1;i++){
                b[i] = b[i - 1] * a[i - 1];
            }
            //将下三角中一行的数字相乘,记作tmp,然后乘入b[i]
            int tmp = 1;
            for(int i = a.length - 2;i >= 0;i--){
                tmp *= a[i + 1];
                b[i] *= tmp;
            }
            return b;
        }
    }

    复杂度分析

    时间复杂度: O(n)
    空间复杂度: O(1)

  • 相关阅读:
    代码
    (转载)计算机的二进制起源
    表的新建
    SQL约束
    包装类
    GUID(转载)
    Android九宫格解锁自定义控件(附源码)
    Android滑动页面返回(自定义控件)
    Android高仿QQ消息滑动删除(附源码)
    Android跟踪球-手势移动图片-自定义控件(附源码)
  • 原文地址:https://www.cnblogs.com/Howfars/p/13399100.html
Copyright © 2011-2022 走看看