LeetCode 238. Product of Array Except Self

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.)

分析:题目要求不能用除法并且时间复杂度要为O(n),这是本题的难点,本题最直观的解法是用循环遍历,代码如下:

public class Solution {
    public int[] productExceptSelf(int[] nums) {
        int [] product = new int[nums.length];
        for(int m = 0; m < nums.length; m++){
            product[m] = 1;
        }
        for(int i = 0; i < nums.length; i++){
            for(int j = 0; j < nums.length ; j++){
                if(j == i) {
                    continue;
                }
                product[i] *= nums[j];
            }
            
        }
        return product;
    }
}
但是此算法的时间复杂度超过要求,可以选择用两个数组(left[]和right[])来分别接收nums[]数组中从左到右和从右到左相乘,值得一提的是,left[]的首元素代表nums[]第零个元素左边的元素之积,不存在可以赋值为1,同理将right[]数组的最后一位也赋值为1。最终结果数组的第i个元素由左右数组的第i个数据相乘即可得到。

代码:

public class Solution {
    public int[] productExceptSelf(int[] nums) {
        int [] product = new int[nums.length];
        int [] left = new int[nums.length];
        int [] right = new int[nums.length];
        left[0] = 1;
        right[nums.length - 1] = 1;
        for(int i = 0;i < nums.length - 1;i++){
            left[i + 1] = left[i] * nums[i];
        }
        for(int i = nums.length - 1;i > 0; i--){
            right[i - 1] = right[i] * nums[i];
        }
        for(int i = 0; i < nums.length; i++){
            product[i] = left[i] * right[i];
        }
        return product;
    }
}

Follow up中提到能否用常量空间复杂度,可以将结果数组存放左边/右边相乘后的结果,然后再和右边/左边相乘后的结果相乘即可得到结果。

代码:

public class Solution {
    public int[] productExceptSelf(int[] nums) {
        // int [] product = new int[nums.length];
        // int [] left = new int[nums.length];
        // int [] right = new int[nums.length];
        // left[0] = 1;
        // right[nums.length - 1] = 1;
        // for(int i = 0;i < nums.length - 1;i++){
        //     left[i + 1] = left[i] * nums[i];
        // }
        // for(int i = nums.length - 1;i > 0; i--){
        //     right[i - 1] = right[i] * nums[i];
        // }
        // for(int i = 0; i < nums.length; i++){
        //     product[i] = left[i] * right[i];
        // }
        // return product;
        int [] product = new int[nums.length];
        product[0] = 1;
        for(int i = 0; i < nums.length - 1; i++){
            product[i + 1] = product[i] *nums[i];
        }
        int right = 1;
        for(int i = nums.length - 1; i >= 0; i--){
            product[i] *= right;
            right *= nums[i];
        }
        return product;
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值