zoukankan      html  css  js  c++  java
  • [LeetCode] 238. Product of Array Except Self(数组除自身元素外的乘积)

    Description

    Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all elements of nums except nums[i].
    给一个数组 nums(长度大于 1),返回一个数组 output,其中 output[i] 等于 nums 数组内除 nums[i] 外所有元素的乘积。

    Example

    Input:  [1,2,3,4]
    Output: [24,12,8,6]
    

    Constraint

    It's guaranteed that the product of the elements of any prefix or suffix of the array (including the whold array) fits in a 32 bit integer.
    输入保证数组的任何子数组的乘积结果都在 32 位整数范围内。

    Note

    Please solve it without division and in O(N).
    不使用除法并在 (O(N)) 内解决它。

    Follow up

    Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)
    你能使用常数额外空间解答吗(用于输出的数组不计入空间复杂度分析)。

    Solution

    假设数组有 4 个元素 [a, b, c, d],那么最后的结果应该是 [bcd, acd, abd, abc],对于每个元素,我们以该元素为界,将其分为前半部分和后半部分,没有的部分用 1 填充,得到如下结果:

    • 前半部分:[1, a, ab, abc]

    • 后半部分:[bcd, cd, d, 1]

    不难看出,分别做一次前缀积和一次后缀积,再将二者相乘,即可得到最终结果,代码如下:

    class Solution {
        fun productExceptSelf(nums: IntArray): IntArray {
            // 前缀积
            val prefix = IntArray(nums.size)
            prefix[0] = 1
            for (i in 1..nums.lastIndex) {
                prefix[i] = nums[i - 1] * prefix[i - 1]
            }
    
            // 后缀积
            val suffix = IntArray(nums.size)
            suffix[nums.lastIndex] = 1
            for (i in nums.lastIndex - 1 downTo 0) {
                suffix[i] = nums[i + 1] * suffix[i + 1]
            }
    
            // 结果
            val result = IntArray(nums.size)
            for (i in nums.indices) {
                result[i] = prefix[i] * suffix[i]
            }
    
            return result
        }
    }
    

    至于 Follow up 里的常数额外空间,我在 discussion 里找了一下,大概思路就是只保留一个前缀积数组,后缀积则是边生成边乘上去,这样可以压缩掉两个额外数组空间,只有返回数组的空间了,代码如下:

    class Solution {
        fun productExceptSelf(nums: IntArray): IntArray {
            val result = IntArray(nums.size)
            result[0] = 1
            for (i in 1..nums.lastIndex) {
                result[i] = result[i - 1] * nums[i - 1]
            }
            var suffix = 1
            for (i in nums.indices.reversed()) {
                result[i] *= suffix
                suffix *= nums[i]
            }
    
            return result
        }
    }
    
  • 相关阅读:
    C++ Sqlite3的基本使用
    DirectX11 初探XMVECOTR&XMMATRIX
    lib和dll文件的初了解
    游戏设计模式——C++单例类
    C++11智能指针的深度理解
    你的文章里为什么不放源码Github链接了
    堡垒机的核心武器:WebSSH录像实现
    Asciinema文章勘误及Web端使用介绍
    Asciinema:你的所有操作都将被录制
    Django实现WebSSH操作物理机或虚拟机
  • 原文地址:https://www.cnblogs.com/zhongju/p/13909150.html
Copyright © 2011-2022 走看看