剑指offer第二版-66.构建乘积数组

本系列导航:剑指offer(第二版)java实现导航帖

面试题66:构建乘积数组

题目要求:
给定数组A[0,1...n-1],求B[0,1...n-1],要求B[i] = A[0]*A[1]...A[i-1]*A[i+1]...A[n-1],不能使用除法。

解题思路:
如果没有不能用除法的限制,可以通过∑A/A[i]求得B[i],同时要注意A[i]等于0的情况。
既然不能使用除法,那就只好用纯乘法计算。如果每一个B中的元素都用乘法计算,那么时间复杂度为0(n^2)。
使用纯乘法,还有更高效的思路。定义C[i]=A[0]*A[1]...A[i-1],那么C[i]=C[i-1]*A[n-1];定义D[i]=A[i+1]*...A[n-2]*A[n-1],那么D[i] =D[i+1]*A[i+1];因此C[i],D[i]都可以递推地求出来,且B[i]=C[i]*D[i]。步骤如下:

1.计算C数组;
2.依次求得D[0],D[1]...D[n-1],同时完成B[i]=C[i]\*D[i]的计算。

如果最终结果存放于result[]中,第一步的C的值就可以先放到result中,
而D的元素可以存放于一个变量temp中,通过result[i] = temp\*result[i]求得B。

时间复杂度o(n),由于计算B必然要申请长度为n的空间,除此之外,该方法仅申请了几个变量,空间复杂度o(1)。

package chapter6;

/**
 * Created with IntelliJ IDEA
 * Author: ryder
 * Date  : 2017/8/21
 * Time  : 8:45
 * Description:构建乘积数组
 **/
public class P313_ConstructArray {
    public static int[] multiply(int[] data){
        if(data==null||data.length<2)
            return null;
        int[] result = new int[data.length];
        //求得数组C,存于result中
        result[0] = 1;
        for(int i=1;i<result.length;i++)
            result[i] = result[i-1]*data[i-1];
        //先求得数组D中元素,再与C中元素相乘,存于result中
        int temp = 1;
        for(int i=data.length-2;i>=0;i--){
            //数组D中的元素值
            temp = temp * data[i+1];
            //计算B[i]=C[i]*D[i]
            result[i] = result[i] * temp;
        }
        return result;
    }
    public static void main(String[] args){
        int[] data = new int[]{1,2,3,4,5};
        int[] result = multiply(data);
        for(int i=0;i<result.length;i++){
            System.out.print(result[i]);
            System.out.print("  ");
        }
    }
}

运行结果

120  60  40  30  24  

推荐阅读更多精彩内容