• 每日一题


    题目信息

    • 时间: 2019-07-07

    • 题目链接:Leetcode

    • tag: 限制运算符号

    • 难易程度:简单

    • 题目描述:

      给定一个数组 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]
    

    注意

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

    解题思路

    本题难点

    不能使用除法,限制运算符号。

    具体思路

    B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]

    B[i]
    B[0] = 1 A[1] A[2] ... A[n-1] A[n]
    B[1] = A[0] 1 A[2] ... A[n-1] A[n]
    B[2] = A[0] A[1] 1 ... A[n-1] A[n]
    ... ... ... ... ... ... ...
    B[n-1] = A[0] A[1] A[2] ... 1 A[n]
    B[n] = A[0] A[1] A[2] ... A[n-1] 1

    根据表格的主对角线(全为 11 ),可将表格分为 上三角下三角 两部分。分别迭代计算下三角和上三角两部分的乘积,即可 不使用除法 就获得结果。

    提示:通过两轮循环,分别计算表格中下三角和上三角的乘积。

    代码

    class Solution {
        public int[] constructArr(int[] a) {
            if(a.length == 0) return new int[0];
          //初始化:数组 B ,其中 B[0]=1 ;辅助变量 tmp=1 ;
            int[] b = new int[a.length];
            b[0] = 1;
            int tmp = 1;
          //计算 B[i] 的 下三角 各元素的乘积,直接乘入 B[i] ;
            for(int i = 1; i < a.length; i++) {
                b[i] = b[i - 1] * a[i - 1];
            }
          //计算 B[i] 的 上三角 各元素的乘积,记为 tmp ,并乘入 B[i] 
            for(int i = a.length - 2; i >= 0; i--) {
                tmp *= a[i + 1];
                b[i] *= tmp;
            }
            return b;
        }
    }
    

    复杂度分析:

    • 时间复杂度 O(N) : 其中 N为数组长度,两轮遍历数组 a,使用 O(N) 时间。
    • 空间复杂度 O(1) : 变量 tmp 使用常数大小额外空间(数组 b作为返回值,不计入复杂度考虑)。

    其他优秀解答

    解题思路

    对称遍历

    • 从左往右遍历累乘,结果保存在数组 left 中,此时 left[i] 表示,A[i]左边所有元素的乘积
    • 然后从右往左遍历累乘,结果保存在数组 right中,此时right[i] 表示获取A[i]右边所有元素的乘积
    • 最后结果数组res[i] =left[i]*right[i]

    代码

    class Solution {
        public int[] constructArr(int[] a) {
            if(a.length == 0 || a == null){
                return new int[0];
            }
            int len = a.length;
            int[] left = new int[len];
            int[] right = new int[len];
            left[0] = 1;
            right[len-1] = 1;
            for(int i = 1 ; i <= len -1; i++){
                left[i] = a[i-1] * left[i-1];
            }
            for(int j = len-2; j >= 0; j-- ){
                right[j] = a[j+1] * right[j+1];
            }
            int[] res = new int[len];
            for(int i = 0; i < len; i++){
                res[i] = left[i] * right[i];
            }
            return res;
        }
    }
    
  • 相关阅读:
    XSS 防御方法总结
    IE浏览器兼容方案
    js 排序算法
    webapck 打包体积优化策略
    webapck 速度优化策略
    Grunt、Gulp和Webpack对比
    数据库中的undo日志、redo日志
    使用sysbench对mysql压力测试
    java -cp & java jar的区别
    使用BenchmarkSQL测试PostgreSQL
  • 原文地址:https://www.cnblogs.com/ID-Wangqiang/p/13288130.html
Copyright © 2020-2023  润新知