[leetcode/lintcode 题解] 国内大厂面试高频题: 数组除了自身的乘积

简介: [leetcode/lintcode 题解] 国内大厂面试高频题: 数组除了自身的乘积

描述
给定n个整数的数组nums,其中n> 1,返回一个数组输出,使得output [i]等于nums的所有除了nums [i]的元素的乘积。
在没有除和O(n)时间内解决

在线评测地址:领扣题库官网

样例1
输入: [1,2,3,4]
输出: [24,12,8,6]
解释:
2*3*4=24
1*3*4=12
1*2*4=8
1*2*3=6
AI 代码解读
样例2
输入: [2,3,8]
输出: [24,16,6]
解释:
3*8=24
2*8=16
2*3=6
AI 代码解读

解题思路
如果暴力计算每个位置的答案值的话,时间会达到O(N^2)。
如果先将所有数乘起来,每个位置除以当前的数,有可能会整型溢出。
观察可以发现,每个数其实就是它前面部分的积乘以后面部分的积。所有前缀的积,通过一次遍历即可算出来,后缀也是一样。我们可以边乘边算前缀积,同时将他乘在结果数组上,这样达到了O(1)的额外空间,同时不用到除法。
代码思路

  1. 令result为一个全是1的数组。
  2. 令前缀积prefixProduct等于1,后缀积postfixProduct等于1。
  3. 正序遍历数组nums,第i个位置先将结果乘上prefixProduct,再将prefixProduct乘上nums[i]。
  4. 逆序遍历数组nums,第i个位置先将结果乘上postfixProduct,再将postfixProduct乘上nums[i]。
  5. 返回result。

复杂度分析
设数组长度为N。
时间复杂度

  • 遍历两次数组,时间复杂度为O(N)。

空间复杂度

  • 只需额外O(1)的时间,记录前缀积和后缀积。

源代码

public class Solution {
    /**
     * @param nums: an array of integers
     * @return: the product of all the elements of nums except nums[i].
     */
    public int[] productExceptSelf(int[] nums) {
        int[] result = new int[nums.length];
        int prefixProduct = 1, postfixProduct = 1;
        
        for (int i = 0; i < result.length; i++) {
            result[i] = 1;
        }
        
        // 将第 i 个位置乘上前 i - 1 个数的积
        for (int i = 0; i < result.length; i++) {
            result[i] *= prefixProduct;
            prefixProduct *= nums[i];
        }
        
        // 将第 i 个位置乘上后面数的积
        for (int i = result.length - 1; i >= 0; i--) {
            result[i] *= postfixProduct;
            postfixProduct *= nums[i];
        }
        
        return result;
    }
}
AI 代码解读

更多题解参考:九章官网solution

目录
打赏
0
0
0
0
6
分享
相关文章
|
2月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
100 1
|
10月前
|
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
99 0
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
|
10月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
72 4
|
10月前
|
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
83 0
Leetcode第三十三题(搜索旋转排序数组)
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
10月前
|
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
166 0
|
10月前
|
C++
【LeetCode 12】349.两个数组的交集
【LeetCode 12】349.两个数组的交集
66 0
|
12月前
|
【Amazon 面试题1】一个数组,里面得数出现的次数是偶数次,只有一个数出现的次数是奇数次,找出那个出现奇数次的数
本文介绍了解决Amazon面试题的一种方法,即在一个所有数字出现次数都是偶数,除了一个数字出现奇数次的数组中,利用异或运算的性质找出出现奇数次的数字,并提供了C语言实现的代码示例。
155 1
这些年背过的面试题——LeetCode
本文是技术人面试系列LeetCode篇,一文带你详细了解,欢迎收藏!

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问