238.給你一個整數數組 nums,返回 數組 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。
題目數據 保證 數組 nums之中任意元素的全部前綴元素和后綴的乘積都在 32 位 整數范圍內。
請 不要使用除法,且在 O(n) 時間復雜度內完成此題。
示例 1:
輸入: nums = [1,2,3,4]
輸出: [24,12,8,6]
示例 2:
輸入: nums = [-1,1,0,-3,3]
輸出: [0,0,9,0,0]
提示:
2 <= nums.length <= 10^5
-30 <= nums[i] <= 30
保證 數組 nums之中任意元素的全部前綴元素和后綴的乘積都在 32 位 整數范圍內
進階:你可以在 O(1) 的額外空間復雜度內完成這個題目嗎?( 出于對空間復雜度分析的目的,輸出數組 不被視為 額外空間。)
- 我們最容易想到的就是先求出所有數的乘積,然后用乘積除以每個數即可,但是題目要求不用除法。那我們肯定是用乘法,我們在求某個元素對應的結果時,只要有左邊數組的乘積和右邊數組的乘積,兩數相乘就是答案,所以我們用兩個數組記錄,left[i] 表示下標為 i 元素左邊數組的乘積,right[i] 表示下標為 i 元素右邊數組的乘積。
-
public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] left = new int[n];// 首位元素左邊沒數字,所以乘積默認為 1left[0] = 1;int[] right = new int[n];// 同理末尾元素右邊沒數字,所以乘積默認為 1right[n-1] = 1;// 獲取每個元素左邊所有元素的乘積for(int i=1;i<n;i++){left[i]=left[i-1]*nums[i-1];}// 獲取每個元素右邊所有元素的乘積for(int i=n-2;i>=0;i--){right[i] = right[i+1]*nums[i+1];}int[] res = new int[n];// 每個元素對應結果等于左右乘積相乘for(int i=0;i<n;i++){res[i]=left[i]*right[i];}return res;}
- 那其實我們在獲取每個元素右邊的乘積的時候,每獲得一個其實就能得到一個元素對應的結果了,所以可以合并第 2,3 個 for 循環
-
public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] left = new int[n];// 首位元素左邊沒數字,所以乘積默認為 1left[0] = 1;int[] right = new int[n];// 同理末尾元素右邊沒數字,所以乘積默認為 1right[n-1] = 1;// 獲取每個元素左邊所有元素的乘積for(int i=1;i<n;i++){left[i]=left[i-1]*nums[i-1];}// 獲取每個元素右邊所有元素的乘積// 同時獲得該元素對應的結果int[] res = new int[n];// 該元素最右邊的結果其實就是左邊所有數的乘積res[n-1] = left[n-1];for(int i=n-2;i>=0;i--){right[i] = right[i+1]*nums[i+1];res[i]=left[i]*right[i];}return res;}
- 上面在獲取右乘積時我們會發現,其實我們的每個 right[i] 只和他的前一個乘積有關,那我們都不需要數組,用一個變量不斷更新即可
-
public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] left = new int[n];left[0] = 1;for(int i=1;i<n;i++){left[i]=left[i-1]*nums[i-1];}int[] res = new int[n];int right = 1;for(int i=n-1;i>=0;i--){res[i] = left[i]*right;right*=nums[i];}return res;}
- 題目最后說能否用 O(1) 的額外空間,結果數組 res 不算,那你直接把 res 當做 left 用即可
-
public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] res = new int[n];res[0] = 1;for(int i=1;i<n;i++){re[i]=res[i-1]*nums[i-1];}int right = 1;for(int i=n-1;i>=0;i--){res[i] *= right;right*=nums[i];}return res;}