题目描述

给定长度为 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. 加密算法比较3DES AES RSA ECC MD5 SHA1等

    加 密算法通常分为对称性加密算法和非对称性加密算法,对于对称性加密算法,信息接收双方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是对数据进行 加解密了.非对称算法与之不同,发送双方A,B事先均 ...

  2. ExternalException (0x80004005): GDI+ 中发生一般性错误

    .net开发的程序用了一个自绘的框架, 平常部署到IIS上都没有问题,今天突然之间这个功能就运行不起来了. 报错:GDI+错误,然后在本地的VS里面运行是没有问题的 百度出来的改Path环境变量.注册 ...

  3. What makes for effective detection proposals? 论文解析

    1 介绍(INTRODUCTION) 本文主要对最近的 proposal 检测方法做一个总结和评价.主要是下面这些方法.  2 Detection Proposal 方法(DETECTION PROP ...

  4. DFS遍历中forward、backward以及cross边的界定

    再来看以下具体例子:

  5. datetime & time

    python有两个和时间相关的模块,datetime和time datetime datetime模块下有四个类 date     日期相关的 time          时间相关的 datetime ...

  6. Spark技术的总结 以及同storm,Flink技术的对比

    spark总结 1.Spark的特点: 高可伸缩性 高容错 基于内存计算 支持多种语言:java,scala,python,R 高质量的算法,比MapReduce快100倍 多种调度引擎:可以运行于Y ...

  7. 自定义Chrome缩放比例

    我想要设置Chrome页面缩放为120%,但是Chrome只提供110% 125%,根本没有让我舒心的缩放比例. 强迫症发作,谷歌了半天没有一个很好的解决方案. 虽然也有不少第三方扩展可以自定义缩放比 ...

  8. 多个文本框录入,使用回车键替找Tab键

    为了快速把form的所有文框输入完毕,我们不必使用鼠标去focus文本框. 在html页中放几个文本框: <div class="DivInput"> <div& ...

  9. 背水一战 Windows 10 (60) - 控件(媒体类): Pointer 涂鸦板, InkCanvas 涂鸦板

    [源码下载] 背水一战 Windows 10 (60) - 控件(媒体类): Pointer 涂鸦板, InkCanvas 涂鸦板 作者:webabcd 介绍背水一战 Windows 10 之 控件( ...

  10. Servlet初步认知

    1 背景概述 在近期的公司项目开发的过程中,笔者初步学习Servlet的开发.配置与使用,本文主要介绍了Servlet的相关概念以及优势说明并附上笔者开发简单样例.今天将笔者学习的心得总结出来与大家分 ...