中国企业黄页信息网,苏州优化件,北京建企业网站,电脑全自动挂机赚钱文章目录 1.问题描述2.难度等级3.热门指数4.解题思路4.1 暴力4.2 左右乘积列表4.3 空间复杂度 O(1) 的方法 参考文献 1.问题描述
给你一个整数数组 nums#xff0c;返回数组 answer #xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据保证… 文章目录 1.问题描述2.难度等级3.热门指数4.解题思路4.1 暴力4.2 左右乘积列表4.3 空间复杂度 O(1) 的方法 参考文献 1.问题描述
给你一个整数数组 nums返回数组 answer 其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据保证数组 nums 之中任意元素的全部前缀元素和后缀的乘积都在 32 位整数范围内。
请不要使用除法且在 O(n) 时间复杂度内完成此题。
示例 1
输入: nums [1,2,3,4]
输出: [24,12,8,6]示例 2
输入: nums [-1,1,0,-3,3]
输出: [0,0,9,0,0]提示
2 nums.length 105
-30 nums[i] 30
保证数组 nums 之中任意元素的全部前缀元素和后缀的乘积都在 32 位整数范围内进阶
你可以在 O(1) 的额外空间复杂度内完成这个题目吗 出于对空间复杂度分析的目的输出数组不被视为额外空间。
2.难度等级
Medium。
3.热门指数
★★★★☆
4.解题思路
这似乎是一个简单的问题可以在线性时间和空间内解决。可以先计算给定数组所有元素的乘积然后对数组中的每个元素 x将乘积除以 x 求得除自身值以外的数组乘积。
然后这样的解决方法有一个问题就是如果输入数组中出现 0那么这个方法就失效了。而且在问题中说明了不允许使用除法运算。这增加了这个问题的难度。
4.1 暴力
遍历数组中的每一个元素将当前元素之外的元素依次相乘然后写到结果数组。
时间复杂度 O(n^2)需要两层遍历第一层为遍历数组中的每一个元素第二层是遍历数组中除当前元素的其他所有元素。
空间复杂度 O(1)。
注意此方法不满足题目 O(n) 时间复杂度要求且在 LeetCode 运行将「超出时间限制」。
下面以 Golang 为例给出实现。
func productExceptSelf(nums []int) []int {products : make([]int, len(nums))for i : range nums {p : 1for j, v : range nums {if j ! i {p * v}}products[i] p}return products
}4.2 左右乘积列表
我们不必将所有数字的乘积除以给定索引处的数字得到相应的答案而是可以利用索引处左侧的所有数字乘积和右侧所有数字的乘积相乘得到答案。
对于给定索引 i我们将使用它左边所有数字的乘积乘以右边所有数字的乘积。
具体步骤如下
初始化两个空数组 L 和 R。对于给定索引 iL[i] 代表的是 i左侧所有数字的乘积R[i] 代表的是 i 右侧所有数字的乘积。我们需要用两个循环来填充 L 和 R 数组的值。对于数组 LL[0]应该是 1因为第一个元素的左边没有元素。对于其他元素L[i]L[i-1]*nums[i-1]。同理对于数组 RR[length-1] 应为 1。length 指的是输入数组的大小。其他元素R[i]R[i1]*nums[i1]。当 R 和 L 数组填充完成我们只需要在输入数组上迭代且索引 i 处的值为L[i]*R[i]。
时间复杂度
O(n)其中 n 指的是数组 nums 的长度。预处理 L 和 R 数组以及最后的遍历计算都是 O(n) 的时间复杂度。
空间复杂度
O(n)其中 n 指的是数组 nums 的长度。使用了 L 和 R 数组去构造答案L 和 R 长度等于数组 nums。
下面以 Golang 为例给出实现。
func productExceptSelf(nums []int) []int {n : len(nums)L : make([]int, n)R : make([]int, n)// 构造左右乘积列表。L[0] 1for i : 1; i n; i {L[i] L[i-1] * nums[i-1]}R[n-1] 1for i : n - 2; i 0; i-- {R[i] R[i1] * nums[i1]}// 遍历数组获取答案。products : make([]int, n)for i : range nums {products[i] L[i]*R[i]}return products
}4.3 空间复杂度 O(1) 的方法
我们可以将上面方法的空间复杂度优化成 O(1)。
由于输出数组不算在空间复杂度内那么我们可以将 L 或 R 数组用输出数组来计算。先把输出数组当作 L 数组来计算然后再动态构造 R 数组得到结果。
具体步骤如下
初始化 answer 数组对于给定索引 ianswer[i] 代表的是 i 左侧所有数字的乘积。构造方式与之前相同只是我们试图节省空间先把 answer 作为方法一的 L 数组。这种方法的唯一变化就是我们没有构造 R 数组而是用一个变量来表示右边元素的乘积。并更新数组 answer[i]answer[i]∗R。然后 R 更新为 RR∗nums[i]其中变量 R 表示的就是索引右侧数字的乘积。
时间复杂度
O(n)其中 n 指的是数组 nums 的长度。
空间复杂度
O(1)输出数组不算进空间复杂度中因此我们只需要常数的空间存放变量。
下面以 Golang 为例给出实现。
func productExceptSelf(nums []int) []int {n : len(nums)// 构造左乘积列表。products : make([]int, n)products[0] 1for i : 1; i n; i {products[i] products[i-1] * nums[i-1]}// 遍历数组获取答案。R : 1for i : n - 1; i 0; i-- {products[i] products[i] * RR * nums[i]}return products
}参考文献
238. 除自身以外数组的乘积 - LeetCode