题目描述

给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

输入: [1,2,3,4]

输出: [24,12,8,6]

说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。

进阶:

你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)

算法

题中明确要求不能使用除法,本可以使用O(n^2)的双for暴力循环求解,但又要求在 O(n) 时间复杂度内。这就需要开动下脑筋,先来分析一下输出是怎么的得到:

24 = 2 * 3* 4

12 = 1 * 3 *4

8 = 1 * 2 * 4

6 = 1 * 2 *3

记保存输出的向量为vec,长度为length。

显然vec[i]上需要填的值 = 前i个数累乘 * 后(length - i - 1)个数累乘

仔细一思考,这个好像可以和动态规划有些关联,毕竟涉及到前i个、后几个连乘这样的关系。现在还处在探索问题的阶段,将问题分为两部分思考,一个是从前往后走,一个是从后往前走,保存它们的累乘结果到2个数组中(先不考虑进阶部分要求的常数空间复杂度),观察这2个数组和我们最终的输出有什么关联。

从前往后

nums 1 2 3 4
dp_forward 1 1 2 6
if i > 0:
dp[i] = (nums[0]到nums[i-1]的累乘)
else:
dp[0] = 1
"""
dp数组的前后值有这么一个数学关系:
dp[i] = dp[i-1] * nums[i-1]
"""

从后往前

为了方便阅读与理解,将nums反转为{4,3,2,1}。套用上面得到的数学关系,可以很轻松的到下面的结果:

nums 4 3 2 1
dp_backward 1 4 12 24

将nums反转为正常顺序{1,2,3,4},表格变为:

nums 1 2 3 4
dp_backward 24 12 4 1

最后一步

我们已经得到从前向后累乘与从后向前累乘的各个位置上的结果,将它们放在一起:

nums 1 2 3 4
dp_forward 1 1 2 6
dp_backward 24 12 4 1

答案呼之欲出,将dp_forward和dp_backward一行对应相乘得到{24,12,8,6}正是需要的输出。

我敢保证这不是偶然,让我们在分析一遍下面这个式子:

vec[i] = 前i个数累乘 * 后(length - i - 1)个数累乘

前i个数累乘正好保存在dp_forward[i]中;同理,后(length - i - 1)个数累乘正好保存在dp_backward[i]中。正因为这样,所以对应相乘,才正好是需要的答案。

进阶部分

在常数空间复杂度内完成这个题目。 出于对空间复杂度分析的目的,输出数组不被视为额外空间。

也就是说,我们最多可以使用一个大小为length的数组外加几个常数这么多的存储空间。

我的想法是从前往后这部分一定要保存在输出数组中,后面从后往前这部分可以直接更新在输出数组中。具体不在赘述,看代码里的注释更好理解。

代码

class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int length = nums.size(); // 输出数组
vector<int> vec(length, 1); /*** 两次遍历,从前往后一次,从后往前一次 ***/ // 从前往后
int mul = 1; for (int i = 1; i < length; i++)
{
mul *= nums[i-1];
vec[i] = mul;
} // 从后往前
mul = 1;
for (int i = length - 2; i >= 0; i--)
{
mul *= nums[i+1];
// 更新在输出数组上,觉得抽象可以动笔画一画
vec[i] *= mul;
} return vec;
}
};

[leetcode]238. 除自身以外数组的乘积的更多相关文章

  1. LeetCode 238. 除自身以外数组的乘积(Product of Array Except Self)

    238. 除自身以外数组的乘积 238. Product of Array Except Self 题目描述 LeetCode LeetCode238. Product of Array Except ...

  2. Java实现 LeetCode 238 除自身以外数组的乘积

    238. 除自身以外数组的乘积 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元 ...

  3. LeetCode 238. 除自身以外数组的乘积( Product of Array Except Self)

    题目描述 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: 输 ...

  4. [LeetCode] 238. 除自身以外数组的乘积 ☆☆☆(左积*右积)

    描述 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: 输入: ...

  5. leetcode 238. 除自身以外数组的乘积 (python)

    给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: 输入: [1 ...

  6. Leetcode题目238.除自身以外数组的乘积(中等)

    题目描述: 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: ...

  7. leecode 238除自身以外数组的乘积

    class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { //用除法必须要 ...

  8. 剑指offer 66. 构建乘积数组(Leetcode 238. Product of Array Except Self)

    剑指offer 66. 构建乘积数组 题目: 给定一个数组A[0, 1, ..., n-1],请构建一个数组B[0, 1, ..., n-1],其中B中的元素B[i] = A[0] * A[1] * ...

  9. LeetCode 81——搜索旋转排序数组 II

    1. 题目 2. 解答 2.1. 方法一 基于 LeetCode 33--搜索旋转排序数组 中的方法二. 当 nums[mid] = nums[right] 时,比如 [1, 1, 2, 1, 1], ...

随机推荐

  1. bootstrap1.2

      <html>   <head>   <meta charset="UTF-8">   <title></title> ...

  2. FastReport使用技巧

    使用技巧篇 1.FastReport中如果访问报表中的对象?       可以使用FindObject方法.      TfrxMemoView(frxReport1.FindObject('memo ...

  3. MySQL--当mysqldump --single-transaction遇到alter table(1)

    部分生产环境采用mysqldump --single-transaction的方式在夜间进行数据库备份,而同事恰好在备份期间执行了alter table操作,操作部分成功部分失败,为啥呢? ##=== ...

  4. MS SQL的某一数据库成了Single User模式

    数据库恢复失败,原来的数据却变成了 当尝试打开数据库的属性,即出现上面图片异常的信息. 正常来说,是可以打开数据库的属性 此刻,你可以运行SQL语句来解决: USE master; GO ALTER ...

  5. 剑指offer编程题Java实现——面试题7用两个栈实现队列

    题目:用两个栈实现一个队列.队列的声明如下:请实现他的两个函数appendTail和deleteHead, 分别完成在队列尾部插入节点和在队列头部删除节点的功能. package Solution; ...

  6. AngularJS指令封装高德地图组件

    1 概述 公司移动门户原来是基于AngularJS指令封装的百度地图组件,用于签到.签退.定位等功能,在使用过程中发现百度地图频繁的弹出广告,所以打算重新引用其它地图组件,最后决定基于AngularJ ...

  7. awk的匹配

    关系运算符 含义 用法示例 < 小于 x < y > 大于 x > y

  8. Web 前端 注意知识点

    一.  前端使用技巧: 1. button的用法.在使用按钮时可以自由在内设置style属性,来改变形态.可以给予type=sbumit提交属性. 2. 各种使用符号: # <!--小于 大于 ...

  9. jq 复习帖子 常用操作

     1绝对定位(abs)与相对定位(relative)    区别是相对定位参照自己的位置进行移动(当然需要设置top left这些生效)并且原来的位置保留着 偏移后会把其它的层遮罩住    绝对定位就 ...

  10. 反向读取Mysql数据库表结构到PowerDesigner中

    使用PowerDesigner挺长时间了,只是一些简单的表结构设计,因需要对当前数据库进行再设计,需要看一下数据库中所有的表,及表之间的关系,并重新修改表结构,因此需求就是怎么把数据库中的表结构反向生 ...