构建乘积数组--java
题目:给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。
解析:这道题,直观的解法是:设置一个循环(由0到n-1),计算B[i]时,忽略掉A[i]项,把数组A中的其他项全部相乘,即得到B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。这样,一次循环过后,就可以在没有除法的条件下,得到数组B中所有的值。那么,这种解法的时间复杂度和空间复杂度是多少呢?时间复杂度:由于循环由0~n-1,即o(n),在每次循环中,要执行n-1次乘法运算,所以这种解法的时间复杂度为o(n)*o(n-1)=o(n2);空间复杂度为o(1)。
显然,上面这种解法的时间复杂度较高,那么有没有o(n)的解法呢?我们不妨分析一下上面这种解法的问题,从而找到可以优化的突破口。上面的复杂度由两部分组成,第一部分:循环由0~n-1,显然我们需要计算每一个B[i],不管怎样,我们都没办法去掉这样的基本循环,也就是说这一部分带来了时间复杂度o(n)不能再进行优化;第二部分:每一次计算B[i]都需要进行n-1次乘法,也即是需要计算n次n-1个数相乘,细心的人可以发现,这里面有很多的乘法是重复的,正是由于这部分重复的乘法计算造成我们的时间复杂度很高。那么,有没有办法只计算一次这样的n-1个数相乘呢?我们可以定义两个中间数组来存储已经计算过得乘法结果,这样,在进行下一个B[i]计算时,我们只需要完成一次乘法就可以得到B[i]的结果了。这样,时间复杂度就变成了o(1),整个算法时间复杂度就降成了o(n)。具体分析思路如下:
首先,我们可以将数组B表示成矩阵的形式如下:
| B[0] | 1 | A[1] | A[2] | ... | A[n-2] | A[n-1] |
| B[1] | A[0] | 1 | A[2] | ... | A[n-2] | A[n-1] |
| B[2] | A[0] | A[1] | 1 | ... | A[n-2] | A[n-1] |
| ... | ... | ... | ... | 1 | ... | ... |
| B[n-2] | A[0] | A[1] | A[2] | ... | 1 | A[n-1] |
| B[n-1] | A[0] | A[1] | A[2] | ... | A[n-2] | 1 |
如上图所示,矩阵的每一行代表数组B的一个元素,从上往下,依次是B[0],B[1],...B[n-2],B[n-1]。那么,我们可以将每一个B[i]看成两部分,分别用C[i]和D[i]表示。其中C[i] = A[0]*A[1]*...*A[i-1],D[i] = A[i+1]*...*A[n-2]*A[n-1],这样,B[i]=C[i]*1*D[i]。也就是说,我们可以每次更新数组C[i]和D[i],即C[i]=C[i-1]*A[i-1]和D[i]=D[i+1]*A[i+1](需要说明的是,这里C[i]的更新是按照从前往后,而D[i]则是从后往前),从而为我们节省了大量的重复的乘法计算,使得时间复杂度降为o(n)。
int[] multiply(int[] A){
if(A==null||A.length<=0)//边界条件,最好附带上
return null;
int n = A.length;
int[] B = new int[n];
B[0]=1;
/*更新C[i],这里我们不另外定义数组,直接将C[i]的计算结果存储在B[i]中,
这样,再将D[i]的结果直接乘以B[i](此时B[i]等于C[i]),就得到了最终
的B[i],显然为我们又节省了不少空间存储。
*/
for(int i=1;i<n;i++){
B[i]=B[i-1]*A[i-1];
}
int temp =1;
//更新D[i],这里要从n-2开始,因为B[n-1]已得到最终结果
for(int j=n-2;j>=0;j--){
temp*=A[j+1];
B[j]*=temp;
}
return B;
}
显然,上述解法的时间复杂度为:2*o(n)*2=o(n)。
构建乘积数组--java的更多相关文章
- 【Java】 剑指offer(66) 构建乘积数组
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 给定一个数组A[0, 1, …, n-1],请构建一个数组B[ ...
- 剑指 Offer 66. 构建乘积数组 + 思维
剑指 Offer 66. 构建乘积数组 Offer_66 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author WaleGarre ...
- 《剑指offer》第六十六题(构建乘积数组)
// 面试题66:构建乘积数组 // 题目:给定一个数组A[0, 1, …, n-1],请构建一个数组B[0, 1, …, n-1],其 // 中B中的元素B[i] =A[0]×A[1]×… ×A[i ...
- 【剑指offer】不使用除法,构建乘积数组,C++实现
# 题目 # 思路 设C[i] = A[0] * A[1] * - * A[i-1],D[i] = A[i+1] * - * A[n-1],则C[i]按照从上到下的顺序计算,即C[i] = C[i- ...
- php实现构建乘积数组(算法:替换)(语法错误:分号和$符号)
php实现构建乘积数组(算法:替换)(语法错误:分号和$符号) 一.总结 1.算法:替换 2.语法错误:分号和$符号 二.php实现构建乘积数组 题目描述: 给定一个数组A[0,1,...,n-1], ...
- 剑指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] * ...
- 剑指offer二刷——数组专题——构建乘积数组
构建乘积数组 题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A ...
- 【剑指offer】51.构建乘积数组
51.构建乘积数组 知识点:数组: 题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0] * A[1] *... * A[i ...
- 力扣 - 剑指 Offer 66. 构建乘积数组
题目 剑指 Offer 66. 构建乘积数组 思路1 按照一般的思路就是将所有的相乘,然后除以每一位数字就是答案,但是题目要求我们不能使用除法,因此我们会想到每次遍历到每个数字的时候,在遍历一遍数组, ...
随机推荐
- java Vamei快速教程11 对象引用
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们之前一直在使用“对象”这个概念,但没有探讨对象在内存中的具体存储方式.这方面的 ...
- 微信小程序 尺寸单位px与rpx之间的转换(入门篇)
1.rpx:微信小程序中的尺寸单位rpx(responsive pixel):可以根据屏幕宽度进行自适应.规定屏幕宽度为750rpx. 微信官方建议视觉稿以iphone6为标准. 2.个人示例测试: ...
- IOS enum(枚举)使用
typedef enum { MJMessageTypeMe=, MJMessageTypeOther }MJMessageType; /** *信息的类型 * */ @property (nonat ...
- 【转】CentOS 7.0 安装Redis 3.2.1详细过程和使用常见问题
http://www.linuxidc.com/Linux/2016-09/135071.htm 环境:CentOS 7.0 Redis 3.2.1 Redis的安装与启动 这里我把Redis放在/h ...
- react 信用卡格式检验
前言: 技术栈主要基于react + ant-design 描述: 填写信用卡卡号时,会自动四位空格,并格式校验判断卡种 ,这里我们业务只涉及到四种卡. 代码解析 // ant 组件自引,这里我只讲 ...
- vue2.0在页面中自定义组件模块,以及页面与组件之间的数据传递
1,在初始文件index.html中加入要引入的模块,注意驼峰命名的方式(我就是没写成驼峰,报错) <!DOCTYPE html> <html> <head> &l ...
- C# 界面跳转-登陆之后跳转至主窗口
在登陆按钮验证成功之后可以将会话结果改为OK //验证通过之后将对话结果设置为OK(之后会载入主界面) this.DialogResult = DialogResult.OK; this.Dispos ...
- nginx.service: Failed to read PID from file /run/nginx.pid: Invalid argument解决
先附上错误信息: (myblog) root@Dapeng:/home/uwsgi# service nginx status ● nginx.service - A high performance ...
- Spring+ ApplicationListener
有时候 需要在容器初始化完成后,加载些 代码字典或不常变的信息 放入缓存之类的,这里使用spring 初始化bean,并实例化 1.创建一个ApplicationListener类 import o ...
- JZ2440开发板与ubuntu互ping,然后进行文件的共享和挂载
操作手册如下:但本人直接用网线直接连通开发板的网口与电脑的网口没有成功过.采用路由器可以直接ping通,具体操作如下: 首先用网线将开发板和路由器连接.电脑无论是用wifi还是网线均可.然后关闭Win ...