Skip to content

Files

面试题66. 构建乘积数组

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
May 30, 2024
Feb 6, 2023
Jan 13, 2024
Feb 6, 2023
Feb 6, 2023
Feb 6, 2023
Feb 6, 2023
May 30, 2024
Jun 19, 2023
comments difficulty edit_url
true
简单

题目描述

给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 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

解法

方法一:两次遍历

我们先创建一个长度为 n 的答案数组 a n s

接下来,我们从左到右遍历数组 a ,过程中维护一个变量 l e f t ,表示当前元素左边所有元素的乘积,初始时 l e f t = 1 。当遍历到 a [ i ] 时,我们将 l e f t 赋值给 a n s [ i ] ,然后 l e f t 乘以 a [ i ] ,即 l e f t l e f t × a [ i ]

然后,我们从右到左遍历数组 a ,过程中维护一个变量 r i g h t ,表示当前元素右边所有元素的乘积,初始时 r i g h t = 1 。当遍历到 a [ i ] 时,我们将 a n s [ i ] 乘上 r i g h t ,然后 r i g h t 乘以 a [ i ] ,即 r i g h t r i g h t × a [ i ]

最终,数组 a n s 即为所求的答案。

时间复杂度 O ( n ) ,其中 n 为数组 a 的长度。忽略答案数组的空间消耗,空间复杂度 O ( 1 )

Python3

class Solution:
    def constructArr(self, a: List[int]) -> List[int]:
        n = len(a)
        ans = [0] * n
        left = right = 1
        for i in range(n):
            ans[i] = left
            left *= a[i]
        for i in range(n - 1, -1, -1):
            ans[i] *= right
            right *= a[i]
        return ans

Java

class Solution {
    public int[] constructArr(int[] a) {
        int n = a.length;
        int[] ans = new int[n];
        for (int i = 0, left = 1; i < n; ++i) {
            ans[i] = left;
            left *= a[i];
        }
        for (int i = n - 1, right = 1; i >= 0; --i) {
            ans[i] *= right;
            right *= a[i];
        }
        return ans;
    }
}

C++

class Solution {
public:
    vector<int> constructArr(vector<int>& a) {
        int n = a.size();
        vector<int> ans(n);
        for (int i = 0, left = 1; i < n; ++i) {
            ans[i] = left;
            left *= a[i];
        }
        for (int i = n - 1, right = 1; ~i; --i) {
            ans[i] *= right;
            right *= a[i];
        }
        return ans;
    }
};

Go

func constructArr(a []int) []int {
	n := len(a)
	ans := make([]int, n)
	for i, left := 0, 1; i < n; i++ {
		ans[i] = left
		left *= a[i]
	}
	for i, right := n-1, 1; i >= 0; i-- {
		ans[i] *= right
		right *= a[i]
	}
	return ans
}

TypeScript

function constructArr(a: number[]): number[] {
    const n = a.length;
    const ans: number[] = Array(n);
    for (let i = 0, left = 1; i < n; ++i) {
        ans[i] = left;
        left *= a[i];
    }
    for (let i = n - 1, right = 1; i >= 0; --i) {
        ans[i] *= right;
        right *= a[i];
    }
    return ans;
}

JavaScript

/**
 * @param {number[]} a
 * @return {number[]}
 */
var constructArr = function (a) {
    const n = a.length;
    const ans = new Array(n);
    for (let i = 0, left = 1; i < n; ++i) {
        ans[i] = left;
        left *= a[i];
    }
    for (let i = n - 1, right = 1; ~i; --i) {
        ans[i] *= right;
        right *= a[i];
    }
    return ans;
};

C#

public class Solution {
    public int[] ConstructArr(int[] a) {
        int n = a.Length;
        int[] ans = new int[n];
        int left = 1, right = 1;
        for (int i = 0; i < n; i++) {
            ans[i] = left;
            left *= a[i];
        }
        for (int i = n - 1; i > -1; i--) {
            ans[i] *= right;
            right *= a[i];
        }
        return ans;
    }
}

Swift

class Solution {
    func constructArr(_ a: [Int]) -> [Int] {
        let n = a.count
        guard n > 0 else { return [] }

        var ans = [Int](repeating: 1, count: n)

        var left = 1
        for i in 0..<n {
            ans[i] = left
            left *= a[i]
        }

        var right = 1
        for i in (0..<n).reversed() {
            ans[i] *= right
            right *= a[i]
        }

        return ans
    }
}