238. Product of Array Except Self leetcode java
題目:
Given an array of n integers where n > 1, nums
, return an array output
such
that output[i]
is equal to the product of all the elements of nums
except nums[i]
.
Solve it without division and in O(n).
For example, given [1,2,3,4]
, return [24,12,8,6]
.
Follow up:
Could you solve it with constant space complexity? (Note: The output array does not
思路:給定一個數組,求除了自身之外的其他元素的乘積,乍一看比較簡單,可以用全部元素的乘積除以當前元素,問題在於有的元素可能是0,分析有元素是0的情況,如果只有一個元素是0,那麼其他元素對應的乘積都是0,而這個為0元素對應的乘積是其他所有元素的乘積。
綜上,分三種情況,多於兩個元素是0,直接退出,返回全為0的結果res;一個元素是0,只計算該元素對應的值,其他元素對應結果為0;沒有元素是0,全部元素乘積除以當前元素。
程式:
class Solution { public int[] productExceptSelf(int[] nums) { int[] res=new int[nums.length]; int product=1;//沒有元素為0的情況下,計算所有元素的乘積 int zero=0;//計算0的個數 int temp=0;//只有一個元素為0的情況下,記錄該index for(int i=0;i<nums.length;i++){ if(nums[i]==0){ temp=i; zero++; if(zero>1) return res; } product*=nums[i]; } if(zero==1){ res[temp]=1; for(int i=0;i<nums.length;i++){ if(i==temp) continue; res[temp]*=nums[i]; } return res; } for(int i=0;i<nums.length;i++){ res[i]=product/nums[i]; } return res; } }
納悶medium的題目怎麼會這麼簡單,仔細看了下要求不能用除法,那麼對於每個nums[i]來說,對應的乘積是它左邊的那部分乘以右邊的那部分,然後用兩次遍歷,分別用res和res2來儲存某個元素左邊和右邊的乘積,比如對於nums[i],res[i]表示這個元素左邊所有數字的乘積,res2[i]表示這個元素右邊所有元素的乘積,最後乘起來就可以了,注意一下邊界。
class Solution { public int[] productExceptSelf(int[] nums) { int len=nums.length; int[] res=new int[len];//用於儲存i左邊的乘積 int[] res2=new int[len];//用於儲存i右邊的乘積 int product=1; int zero=0; int temp=0; for(int i=0;i<len;i++){ if(nums[i]==0){ temp=i; zero++; if(zero>1) return res; } product*=nums[i]; } if(zero==1){ res[temp]=1; for(int i=0;i<len;i++){ if(i==temp) continue; res[temp]*=nums[i]; } return res; } res[0]=1; for(int i=1;i<len;i++){ res[i]=res[i-1]*nums[i-1]; } res2[len-1]=1; for(int j=len-2;j>=0;j--){ res2[j]=res2[j+1]*nums[j+1]; } for(int i=0;i<len;i++){ res[i]=res[i]*res2[i]; } return res; } }
題目中還有一個要求,O(1)的空間複雜度,所以把陣列res2用rightproduct代替,rightproduct表示當前元素的右邊的元素的乘積,邊計算,邊直接乘到結果res上。
class Solution {
public int[] productExceptSelf(int[] nums) {
int len=nums.length;
int[] res=new int[len];//用於儲存i左邊的乘積
int rightproduct=1;//節省空間複雜度,用於儲存當前元素右邊的乘積
int zero=0;
int temp=0;
for(int i=0;i<len;i++){
if(nums[i]==0){
temp=i;
zero++;
if(zero>1)
return res;
}
}
if(zero==1){
res[temp]=1;
for(int i=0;i<len;i++){
if(i==temp)
continue;
res[temp]*=nums[i];
}
return res;
}
res[0]=1;
for(int i=1;i<len;i++){
res[i]=res[i-1]*nums[i-1];
}
for(int j=len-2;j>=0;j--){
rightproduct*=nums[j+1];
res[j]=res[j]*rightproduct;
}
return res;
}
}