动态规划-构建乘积数组

**

描述

给定一个数组 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](除 A[i] 以外的全部元素的的乘积)。程序中不能使用除法。(注意:规定 B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2])
对于 A 长度为 1 的情况,B 无意义,故而无法构建,用例中不包括这种情况。

数据范围:1≤n≤10 ,数组中元素满足 ∣val∣≤10
示例1
输入:
[1,2,3,4,5]
返回值:
[120,60,40,30,24]
示例2
输入:
[100,50]
复制
返回值:
[50,100]

题目分析

这题算个easy的题,原因是它的暴力解法很简单。如果要求时间复杂度是o(n),我觉得可以算作一个mediem题。题目描述的很清晰,没什么弯弯绕绕,就是要我们输出一个给定数组乘积的数组,数组的每一项都分别少乘一个数。

题解

暴力解法

暴力解法很简单,直接根据题意,每次乘的时候少乘一个数,2次for循环就能解决问题,下面直接上代码。

import java.util.*;
public class Solution {
    public int[] multiply (int[] A) {
        int[] b= new int[A.length];
        for(int i=0;i<A.length;i++){
            int res = 1;
            for(int j=0;j<A.length;j++){
                if(i==j) continue;
                res = res*A[j];
            }
            b[i] = res;
        }
        return b;
    }
}

暴力解法不做过度解释,相信大家都能看懂,同时它的时间复杂度也达到了惊人的o(n2)

两次遍历

为了降低暴力解法的时间复杂度,我们必须得有利用空间来置换时间的想法。我们可以把数组B的结果用一个表格来列举出来,如下图:
B数组结果
我们可以先忽略掉B[n]这一行,直接看带有A的举证
矩阵A
我们可以看到,这个矩阵以1为分割线,将矩阵分为了上下两个三角形。而B的结果就是这个矩阵每一行的乘积。
下三角用连乘可以很容求得,上三角,从下向上其实也是连乘。

因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[n]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去,两次遍历,结果就出来了。

接下来我们直接上代码:

import java.util.*;
public class Solution {
    public int[] multiply (int[] A) {
        int[] b= new int[A.length];
        b[0] = 1;
        //第一次遍历算上三角,也就是对角线下面的三角形,我们根据规律可以看出b[0]的值直
        //接就是1,后面b[i]的值就是上一层b[i-1]的值乘上A[i-1]即可。
        for(int i=1;i<A.length;i++){
            b[i] = A[i-1]*b[i-1];
        }
        //第二次遍历,我们再把下三角累乘出来,分别跟上面的b[i]做乘积,这样每层的结果就
        //出来了,同时我们需要一个temp临时变量来记录每次累乘的结果
        int temp = 1;
        for(int i=A.length-1;i>=0;i--){
        //每次累乘的结果乘上b[i]就是那一行的值咯
            b[i] = b[i]*temp;
            /再进行下一次累乘
            temp = temp*A[i];  
        }
        return b;
    }
}

动态规划

说到动态规划,我们肯定会想到动态规划的三个步骤
1.确定状态
2.定义状态转移方程
3.求得最优解

其实上面两次遍历的思想我们稍微进行转变一下,就可以变成动态规划了,我们把第一次为了计算上三角而遍历累乘的结果利用动态规划数组进行存储起来,然后再反向对动态规划数组的结果和下三角逐行相乘即可得到结果数组。

1.确定状态

我们利用动态规划主要是为了保存上三角的值,那么dp[0]=1;

2.定义状态转移方程

状态转移方程肯定就是三角下一行的值等于上一行的值乘以A数组上一行对应下标的值,也就是dp数组第i行的值等dp数组第i-1行的值乘上A数组第i-1的下标的值。
转换成代码形式就是
dp[i] = dp[i-1]*A[i-1]

3.求得最优解

得到上三角的值,我们再反向对动态规划数组的结果和下三角逐行相乘即可得到结果数组。
其实我们只需要将两次遍历的代码中B数组用dp数组代替就可以了,代码其实可以是一摸一样的,是不是很容易。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/128893.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

量子计算和量子通信技术:引领潜力无限的未来

近年来&#xff0c;随着量子计算和量子通信技术的迅速发展&#xff0c;它们在各个领域的广泛应用前景引起了人们的极大兴趣。本文将深入探讨量子计算和量子通信技术的普遍应用&#xff0c;以及它们预示的未来&#xff0c;同时提出业内人士需要注意的事项。 介绍&#xff1a;量子…

【Spring之底层核心架构概念解析】

文章目录 一、BeanDefinition二、BeanDefinitionReader2.1、AnnotatedBeanDefinitionReader2.2、XmlBeanDefinitionReader 五、ClassPathBeanDefinitionScanner六、BeanFactory七、ApplicationContext7.1、AnnotationConfigApplicationContext7.2、ClassPathXmlApplicationCont…

E云管家个微协议框架--新版本的利器

在互联网时代&#xff0c;高效、可靠的互联网协议对于实现稳定、安全的数据传输至关重要。E云管家作为一项创新性的IPAD协议构建工具&#xff0c;基于IPAD8.0.37协议为开发者提供了强大而灵活的功能&#xff0c;使他们能够轻松构建高效的通信协议。本文将介绍E云管家的主要特点…

python3.8及以上版本绑定gdal库的一个注意事项

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> gdal和python绑定参考文章&#xff1a;windows环境下python和gdal绑定方法   值得注意的是绑定python3.8及以上版本后在python程序中初始化gdal库时会出…

“三门问题”解决方案:换不换?更换策略与贝叶斯策略?附 Java 验证代码

文章目录 前言一、什么是“三门问题”&#xff1f;二、“三门问题”解决策略详解2.1、错误策略&#xff1a;直觉策略与随机策略2.2、更换策略与事件分析计算2.3、贝叶斯策略及分析流程 三、Java 语言验证“三门问题”总结 前言 “三门问题”作为一道经典逻辑推理题&#xff0c;…

【Linux】Linux常用命令—用户管理

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

《QT从基础到进阶·二十》QThreadPool线程池的使用

什么情况下比较适合用线程池&#xff1f; 比如我有上百个任务要同时处理&#xff0c;难道开上百个线程&#xff1f;NO&#xff01;&#xff01;&#xff01; 有了线程池的加持&#xff0c;自动给任务分配线程处理&#xff0c; 多线程不再是真爱~ 线程池创建&#xff1a; 1、自…

【带头学C++】----- 四、动态内存空间申请 ---- 4.1 动态内存分配

1.动态内存分配概述 在C和C等语言中&#xff0c;可以使用malloc、calloc、realloc或使用new等函数来动态分配内存空间&#xff0c;同时使用free、delete函数释放动态分配的内存空间&#xff0c;这样可以根据程序的实际需要动态管理内存&#xff0c;避免静态内存分配的局限性。 …

微信超实用的小功能

微信真的有超多实用小功能 平时很少注意到&#xff0c;每次都用传统的方法解决&#xff0c;浪费人家研发人员的一片苦心~ 1重要事项提醒&#xff1a;健忘症的福音&#xff1b; 步骤&#xff1a;长按消息-提醒-设置。 2 图片翻译&#xff1a;不用跳转翻译软件&#xff0c;一键翻…

什么是自动化测试框架?我们该如何搭建自动化测试框架?

无论是在自动化测试实践&#xff0c;还是日常交流中&#xff0c;经常听到一个词&#xff1a;框架。之前学习自动化测试的过程中&#xff0c;一直对“框架”这个词知其然不知其所以然。 最近看了很多自动化相关的资料&#xff0c;加上自己的一些实践&#xff0c;算是对“框架”…

数据分析-numpy

numpy numpy numpy简介优点下载ndarray的属性输出数据类型routines 函数ndarray对象的读写操作ndarray的级联和切分级联切分 ndarray的基本运算广播机制&#xff08;Broadcast&#xff09;ndarry的聚合操作数组元素的操作numpy 数学函数numpy 查找和排序 写在最后面 简介 nump…

js 变量声明与赋值 笔试踩坑题

文章目录 概述函数声明函数形参与实参函数预编译用一个例子说明一下&#xff0c;这四个步骤分别要干些什么。重复四个步骤&#xff0c;反复练习一下 全局编译多重执行期上下文 概述 别小看变量声明与赋值&#xff0c;在所有的笔试中&#xff0c;基本都会考&#xff0c;这个要多…

LeetCode刷题总结(一)

文章目录 前言题型排序问题动态规划 前言 本文把刷题过程中的总结记下来&#xff0c;方便未来回顾的时候继续拓展。 题型 排序问题 排序问题的解决方法有很多。对于简单算法来说&#xff0c;最重要的是记住思路&#xff1b;对于高级算法来说&#xff0c;最重要的是记住细节…

asp.net core weapi 结合identity完成登录注册

1.安装所需要的nuget包 <PackageReference Include"Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version"6.0.24" /><PackageReference Include"Microsoft.EntityFrameworkCore" Version"6.0.24" /><PackageR…

工作利器!熟悉这几款数据流图工具,事半功倍!

数据流图工具在现代工作中起到了非常重要的作用。无论是在企业内部的流程优化&#xff0c;还是在软件开发、项目管理、系统设计等领域&#xff0c;数据流图工具都扮演着关键的角色。本文将为大家介绍8款高效的数据流图工具&#xff0c;帮助大家选择适合自己工作需求的工具。 1.…

创建Springboot工程

前期准备 查看是否安装Java;javac命令是否可用; java -version javac 都安装好之后可以进行创建。 步骤 此处我是使用IntelliJ IDEA 进行创建 打开新建项目–选择Spring Initializr 服务器URL&#xff1a;可以使用默认 &#xff0c; 如果感觉太慢可以选择 http://start.a…

原厂监视综合控制继电器 ZZS-7/1 AC220V 凸出端子固定安装

ZZS-7/11分闸、合闸、电源监视综合控制装置&#xff1b; ZZS-7/12分闸、合闸、电源监视综合控制装置&#xff1b; ZZS-7/13分闸、合闸、电源监视综合控制装置&#xff1b; ZZS-7/14分闸、合闸、电源监视综合控制装置&#xff1b; ZZS-7/102分闸、合闸、电源监视综合控制装置…

基于51单片机的万年历-脉搏计仿真及源程序

一、系统方案 1、本设计采用51单片机作为主控器。 2、DS1302采集年月日时分秒送到液晶1602显示。 3、按键年月日时分秒&#xff0c;心率报警上下限。 4、红外对接管传感器采集心率送到液晶1602显示。 5、心率低于下限或高于上限&#xff0c;蜂鸣器报警。 二、硬件设计 原理图如…

vue+nodejs商城实战项目【登录 + 购物车 + 支付】

从零开始一个前端项目并将其完成需要经历一系列步骤。以下是一个常见的开发流程&#xff0c;可以帮助规划和管理项目&#xff1a; 需求分析和规划&#xff1a; 确定项目的目标和范围。定义用户需求和功能要求。制定项目计划和时间表。 技术选型&#xff1a; 选择适当的前端技术…

4面百度软件测试工程师的面试经验总结

没有绝对的天才&#xff0c;只有持续不断的付出。对于我们每一个平凡人来说&#xff0c;改变命运只能依靠努力幸运&#xff0c;但如果你不够幸运&#xff0c;那就只能拉高努力的占比。 2023年7月&#xff0c;我有幸成为了百度的一名测试工程师&#xff0c;从外包辞职了历经100…