1. 程式人生 > >238. Product of Array Except Self leetcode java

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

 count as extra space for the purpose of space complexity analysis.)

思路:給定一個數組,求除了自身之外的其他元素的乘積,乍一看比較簡單,可以用全部元素的乘積除以當前元素,問題在於有的元素可能是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;
    }
}