小哆啦解题记:如何计算除自身以外数组的乘积

小哆啦开始力扣每日一题的第十二天

https://leetcode.cn/problems/product-of-array-except-self/description/

《小哆啦解题记:如何计算除自身以外数组的乘积》

在一个清晨的阳光下,小哆啦坐在书桌前,思索着一道困扰已久的题目:

给定一个整数数组 nums,返回一个新的数组 answer,其中 answer[i] 等于 nums 中所有元素的乘积,除了 nums[i] 本身。

“这看起来不复杂吧?”小哆啦轻声自语,脑海里已经开始快速构建解题思路。看似简单的题目,背后却藏着优化的挑战。他决定从最基础的方法开始,尽管他并不期待它能跑得很快。

第一步:用双重循环解决问题

“最直接的方式是什么?”小哆啦问自己,随后他选择了使用两个嵌套的 for 循环来解决问题。对于每个元素,他都会计算数组中除了它自己以外的所有元素的乘积。

function productExceptSelf(nums: number[]): number[] {const n = nums.length;const answer: number[] = new Array(n);for (let i = 0; i < n; i++) {let product = 1;for (let j = 0; j < n; j++) {if (i !== j) {product *= nums[j];}}answer[i] = product;}return answer;
}

然而,当他输入一组较大的数字时,程序的速度开始变得异常缓慢。每次都要做两层循环,计算每个元素的乘积,这样的时间复杂度是 O(n2)) 。这显然不是一个高效的解法。

“嗯,看起来我得换个思路了。”小哆啦皱了皱眉头,开始思考如何避免重复计算。

第二步:寻找高效解法

小哆啦坐在书桌前,突然灵光一闪:“如果我计算出数组中每个元素左边的乘积,再计算出右边的乘积,然后结合起来,不就能避免重复计算吗?”这一瞬间,他感觉找到了答案。

他决定实现一个新思路:分别计算出每个元素左边和右边的乘积,然后将它们相乘。这样每个位置的答案就能得到,且时间复杂度将降到 O(n)

第三步:前缀积和后缀积的巧妙结合

小哆啦迅速动手实现这个新思路。首先,他计算出每个元素左边的所有元素的乘积(前缀积),然后计算每个元素右边的乘积(后缀积)。最后,将两者相乘即可得到最终的答案。

function productExceptSelf(nums: number[]): number[] {const n = nums.length;const answer: number[] = new Array(n).fill(1);// 计算前缀积let prefix = 1;for (let i = 0; i < n; i++) {answer[i] = prefix;prefix *= nums[i];}// 计算后缀积并更新结果let suffix = 1;for (let i = n - 1; i >= 0; i--) {answer[i] *= suffix;suffix *= nums[i];}return answer;
}
第四步:高效的实现,快速的运行

小哆啦再次运行代码。这一次,进度条飞速前进,几乎在眨眼之间就得到了正确的结果!

“太棒了!终于解决了。”小哆啦松了口气,心里充满了成就感。这种方法的时间复杂度是 O(n) ,比之前的暴力方法快得多,而且它只使用了常数空间存储前缀积和后缀积,空间复杂度为 O(1) ,除了结果数组。

第五步:胜利的微笑

回想这一路的艰难与突破,小哆啦感到十分满足。每一个程序员的成长,都是在一次次挑战中找到突破口的过程。从最初的双重循环到最后的前缀积和后缀积的优化,这不仅仅是一个简单的算法问题,而是一次智慧的提升。

他站起身来,望着窗外的蓝天,嘴角微微上扬:“未来的道路还很长,我会继续走下去,发现更多的优化和突破。”


结语:优化的思维,突破的力量

小哆啦的解题历程,给我们带来了深刻的启示:对于一个看似简单的问题,背后往往隐藏着对效率和优化的深刻理解。通过巧妙地运用前缀积和后缀积的方式,我们能够在 O(n) 的时间复杂度内高效地解决问题,避免了重复计算。

每次的挑战背后,都是对思维和能力的一次锤炼。当我们能够突破常规的思维方式,才能真正在算法的世界中找到属于自己的道路。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS宏进阶:正则表达式的使用

正则表达式&#xff0c;对于任何一门编程语言来说&#xff0c;都是一种非常强大的工具&#xff0c;主要用于搜索、编辑或操作文本和数据。因此&#xff0c;在JS中&#xff0c;也存在相应的对象new RegExp( )&#xff0c;在本章中&#xff0c;将详细介绍正则表达式在JS宏中的运用…

在 Kubernetes 上快速安装 KubeSphere v4.1.2

目录标题 安装文档配置repo安装使用插件 安装文档 在 Kubernetes 上快速安装 KubeSphere 配置repo export https_proxy10.10.x.x:7890 helm repo add stable https://charts.helm.sh/stable helm repo update安装 helm upgrade --install -n kubesphere-system --create-name…

细说STM32F407单片机电源低功耗StopMode模式及应用示例

目录 一、停止模式基础知识 1、进入停止模式 2、停止模式的状态 3、退出停止模式 4、SysTick定时器的影响 二、停止模式应用示例 1、示例功能和CubeMX项目配置 &#xff08;1&#xff09;时钟 &#xff08;2&#xff09;RTC &#xff08;3&#xff09;ADC1 &#xf…

JavaScript学习笔记(1)

html 完成了架子&#xff0c; css 做了美化&#xff0c;但是网页是死的&#xff0c;我们需要给他注入灵魂&#xff0c;所以接下来我们需要学习 JavaScript&#xff0c;这门语言会让我们的页面能够和用户进行交互。 一、引入方式 1.内部脚本 将 JS 代码定义在 HTML 页面中 Jav…

【三维分割】Gaga:通过3D感知的 Memory Bank 分组任意高斯

文章目录 摘要一、引言二、主要方法2.1 3D-aware Memory Bank2.2 三维分割的渲染与下游应用 三、实验消融实验应用: Scene Manipulation 地址&#xff1a;https://www.gaga.gallery 标题&#xff1a;Gaga: Group Any Gaussians via 3D-aware Memory Bank 来源&#xff1a;加利福…

Day 14 卡玛笔记

这是基于代码随想录的每日打卡 226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;r…

|Python新手小白中级教程|第三十章:日期与时间(入门)

文章目录 前言一、日期与时间的基本概念二、时间戳1.概念2.形成过程 三、Python的时间格式化符号四、时间元组1.时间元组&#xff1a;2.struct_time元组的属性 五、time库可以干什么总结 前言 大家好呀&#xff0c;BOBO仔回来啦。 说实话&#xff0c;这几天我们学习面向对象的…

代码随想录刷题day13|(链表篇)24.两两交换链表中的结点

目录 一、链表理论基础 二、思路及易错点 易错点 三、相关算法题目 四、错误代码分析 一、链表理论基础 代码随想录 (programmercarl.com) 二、思路及易错点 该题使用虚拟头结点正常进行模拟即可&#xff0c;有两个关键点&#xff0c;一是循环何时终止&#xff1f;终止…

PIC单片机设置bootloader程序和app程序地址方法

在调试bootloader和app程序的时候通常都需要设置程序的偏移地址&#xff0c;下面就总结一下使用MPLAB X IDE 设置程序地址的方法。 打开bootloader工程 工程上单击鼠标右键&#xff0c;选择Properties,打工工程属性窗口。 此时会打开项目属性对话框 左边类别选择XC8 Line…

51c大模型~合集105

我自己的原文哦~ https://blog.51cto.com/whaosoft/13101924 #刚刚&#xff0c;ChatGPT开始有了执行力&#xff01; 现在 AI 智能体可以 24*7 小时为你打工。 2025 刚过去了半个月&#xff0c;OpenAI 在智能体领域「开大」了。 今天&#xff0c;OpenAI 正在为 ChatGPT 推出…

迅为龙芯2K1000开发板/核心板流畅运行Busybox、Buildroot、Loognix、QT5.12系统

硬件配置 国产龙芯处理器&#xff0c;双核64位系统&#xff0c;板载2G DDR3内存&#xff0c;流畅运行Busybox、Buildroot、Loognix、QT5.12 系统! 接口全板载4路USB HOST、2路千兆以太网、2路UART、2路CAN总线、Mini PCIE、SATA固态盘接口、4G接口、GPS接口WIF1、蓝牙、Mini H…

StarRocks强大的实时数据分析

代码仓库&#xff1a;https://github.com/StarRocks/starrocks?tabreadme-ov-file StarRocks | A High-Performance Analytical Database 快速开始&#xff1a;StarRocks | StarRocks StarRocks 是一款高性能分析型数据仓库&#xff0c;使用向量化、MPP 架构、CBO、智能物化…

web前端1--基础

&#xff08;时隔数月我又来写笔记啦~&#xff09; 1、下载vscode 1、官网下载&#xff1a;Visual Studio Code - Code Editing. Redefined 2、步骤&#xff1a; 1、点击同意 一直下一步 勾一个创建桌面快捷方式 在一直下一步 2、在桌面新建文件夹 拖到vscode图标上 打开v…

基于tldextract提取URL里的子域名、主域名、顶级域

TLD是TopLevel Domain的缩写。‌tldextract‌ 是一个用于从URL中提取子域、主域名和顶级域&#xff08;TLD&#xff09;的Python库。它利用公共后缀列表&#xff08;Public Suffix List&#xff09;来确保即使是复杂或不常见的URL结构也能被正确解析。tldextract能够处理包括IC…

音频入门(一):音频基础知识与分类的基本流程

音频信号和图像信号在做分类时的基本流程类似&#xff0c;区别就在于预处理部分存在不同&#xff1b;本文简单介绍了下音频处理的方法&#xff0c;以及利用深度学习模型分类的基本流程。 目录 一、音频信号简介 1. 什么是音频信号 2. 音频信号长什么样 二、音频的深度学习分…

数据结构之堆排序

文章目录 堆排序版本一图文理解 版本二向下调整建堆向上调整建堆 排升/降序升序 堆排序 版本一 基于已有数组建堆取堆顶元素并删除堆顶元素重新建大根堆&#xff0c;完成排序版本。 图文理解 版本二 前提&#xff1a;必须提供有现成的数据结构堆 数组建堆&#xff0c;首尾…

小菜鸟系统学习Python第三天

1.优先级问题: 结论: 幂运算>正负号>加减乘除和整除>比较运算符>逻辑运算符 2.三元运算符 3.assert断言:抛出AssertionError异常 4.for循环 4. 5.break和continue

常用排序算法之插入排序

目录 前言 一、基本原理 1.算法步骤 2.动画演示 3.插入排序的实现代码 二、插入排序的时间复杂度 1. 时间复杂度 1.最优时间复杂度 2.最差时间复杂度 3.平均时间复杂度 2. 空间复杂度 三、插入排序的优缺点 1.优点 2.缺点 四、插入排序的改进与变种 五、插入排…

数据分析及应用:经营分析中的综合指标解析与应用

目录 1. 市场份额(Market Share) 2. 客户获取成本(Customer Acquisition Cost, CAC) 3. 客户生命周期价值(Customer Lifetime Value, CLV) 4. 客户留存率(Customer Retention Rate, CRR) 5. 净推荐值(Net Promoter Score, NPS) 6. 转化率(Conversion Rate) …

工业相机 SDK 二次开发-Halcon 插件

本文介绍了 Halcon 连接相机时插件的使用。通过本套插件可连接海康 的工业相机。 一. 环境配置 1. 拷贝动态库 在 用 户 安 装 MVS 目 录 下 按 照 如 下 路 径 Development\ThirdPartyPlatformAdapter 找到目录为 HalconHDevelop 的文 件夹&#xff0c;根据 Halcon 版本找到对…