leetcode238:除自身以外数组的乘积
文章目录
- 1.使用除法(违背题意)
- 2.左右乘积列表
- 3.空间复杂度为O(1)的方法
在leetcode上刷到了这一题,一开始并没有想到好的解题思路,写篇博客再来梳理一下吧。

题目要求:
- 不使用除法
- 在O(n)时间复杂度内
1.使用除法(违背题意)
该方法分以下几步:
- 先遍历数组,求数组所有元素的乘积sum
- 再遍历一遍数组,使用sum除以该下标对应的元素,将结果放在answer数组中

#include<stdio.h>
#include<stdlib.h>
int* productExceptSelf(int* nums, int numsSize, int* returnSize) {int* answer = (int*)calloc(numsSize, sizeof(int));*returnSize = numsSize;int sum = 1;for (int i = 0; i < numsSize; i++){sum *= nums[i]; //求所有元素的乘积}for (int i = 0; i < numsSize; i++){answer[i] = sum / nums[i];}return answer;
}int main()
{int arr[] = { 1,2,3,4 };int sz = sizeof(arr) / sizeof(arr[0]);int count = 0;int* ret = productExceptSelf(arr, sz, &count);for (int i = 0; i < count; i++){printf("%d", *(ret + i));if (i != count - 1){printf(",");}}free(ret);ret = NULL;return 0;
}
2.左右乘积列表
相较于第一种方法,我们不必将所有数字的乘积除以给定索引处的数字得到相应的答案,而是利用索引左侧所有数字的乘积和右侧所有数字的乘积(即前缀与后缀)相乘得到答案。这也是题目中暗示我们的

该方法分以下几步:
- 初始化两个空数组 Left 和 Right。对于给定下标 i,
Left[i] 代表的是 i 左侧所有数字的乘积,Right[i] 代表的是 i 右侧所有数字的乘积。 - 对于数组 Left,Left[0] 应该是 1,因为第一个元素的左边没有元素。对于数组 Right,Right[length-1] 应为 1,因为最后一个元素右侧没有元素。(length 指的是输入数组的大小)
- 对于其它的元素,Left[i] = Left[i-1] * nums[i-1] (i从1开始 i++)

- 对于其它的元素,Right[i] = Right[i+1] * nums[i+1] (i从length-2开始 i–)

- 当 Left 和 Right 数组填充完成,我们只需要在输入数组上迭代:answer[i] = Left[i] * Righti]
#include<stdio.h>
#include<stdlib.h>
int* productExceptSelf(int* nums, int numsSize, int* returnSize) {int* answer = (int*)calloc(numsSize, sizeof(int));*returnSize = numsSize;int Left[numsSize];int Right[numsSize];Left[0] = 1;Right[3] = 1;for (int i = 1; i < numsSize; i++){Left[i] = Left[i - 1] * nums[i - 1];}for (int i = 2; i >= 0; i--){Right[i] = Right[i + 1] * nums[i + 1];}for (int i = 0; i < numsSize; i++){answer[i] = Left[i] * Right[i];}return answer;
}int main()
{int arr[] = { 1,2,3,4 };int sz = sizeof(arr) / sizeof(arr[0]);int count = 0;int* ret = productExceptSelf(arr, sz, &count);for (int i = 0; i < count; i++){printf("%d", *(ret + i));if (i != count - 1){printf(",");}}free(ret);ret = NULL;return 0;
}
复杂度分析:
- 时间复杂度:O(N),其中 N 指的是数组 nums 的大小。预处理 Left 和 Right 数组以及最后的遍历计算都是 O(N)的时间复杂度。
- 空间复杂度:O(N),其中 N 指的是数组 nums 的大小。使用了 Left 和 Right 数组去构造答案,Left 和 Right 数组的长度为数组 nums 的大小。
3.空间复杂度为O(1)的方法
由于输出数组不算在空间复杂度内,而且我们的answer数组只有最后才被用到,所以我们可以先将 Left 或 Right 数组用answer数组来计算。
该方法分为以下几步:
- 先把answer数组当作 Left数组来计算,然后再动态构造 Right 数组得到结果。这样我们就节省了两个数组,空间复杂度就为O(1)了。
- 动态构造Right数组我们只使用一个变量R就可以了,该变量初始化为1。R * nums[i] 即可得到最终的结果.

#include<stdio.h>
#include<stdlib.h>
int* productExceptSelf(int* nums, int numsSize, int* returnSize) {int* answer = (int*)calloc(numsSize, sizeof(int));*returnSize = numsSize;int left[numsSize];int right[numsSize];answer[0] = 1;int R = 1;//先求前缀之积for (int i = 1; i < numsSize; i++){answer[i] = answer[i - 1] * nums[i - 1];}//求后缀之积与answerfor (int i = numsSize - 1; i >= 0; i--){// 对于下标 i,左边的乘积为 answer[i],右边的乘积为 Ranswer[i] = answer[i] * R;// R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上R *= nums[i];}return answer;
}int main()
{int arr[] = { 1,2,3,4 };int sz = sizeof(arr) / sizeof(arr[0]);int count = 0;int* ret = productExceptSelf(arr, sz, &count);for (int i = 0; i < count; i++){printf("%d", *(ret + i));if (i != count - 1){printf(",");}}free(ret);ret = NULL;return 0;
}
复杂度分析
- 时间复杂度:O(N),其中 NNN 指的是数组 nums 的大小。分析与方法一相同。
- 空间复杂度:O(1),输出数组不算进空间复杂度中,因此我们只需要常数的空间存放变量。
目前想到的方法就这些,后续想到会补充。
相关文章:
leetcode238:除自身以外数组的乘积
文章目录 1.使用除法(违背题意)2.左右乘积列表3.空间复杂度为O(1)的方法 在leetcode上刷到了这一题,一开始并没有想到好的解题思路,写篇博客再来梳理一下吧。 题目要求: 不使用除法在O(n)时间复杂度内 1.使用除法&am…...
VTK开发调试环境下载(VTK开发环境一步到位直接开发,无需自己配置编译 VS2017+Qt5.12.10+VTK)
一、无与伦比的优势 直接下载代码就可以调试的VTK代码仓库。 二、资源制作原理 这个资源根据VTK源码 编译出动态库文件 pdb lib dll 文件( x64 debug ) 并将这两者同时放在一个代码仓库里,下载就能用。 三、使用方法(vtk-so…...
【JAVA】在 Queue 中 poll()和 remove()有什么区别
🍎个人博客:个人主页 🏆个人专栏:JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 poll() 方法: remove() 方法: 区别总结: 结语 我的其他博客 前言 在Java的Queue接口中&…...
常用Java代码-Java中的Optional类和null安全编程
在Java中,Optional 是一个可以为null的容器对象。如果值存在则isPresent()方法返回true。调用get()方法会返回值,如果值为null则抛出NullPointerException。以下是一个详细的代码详解。 在之前的Java版本中,程序员需要手动检查是否为null&am…...
android.os.NetworkOnMainThreadException
问题 android.os.NetworkOnMainThreadException详细问题 核心代码如下: import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ja…...
Java生成四位数随机验证码
引言: 我们生活中登录的时候都要输入验证码,这些验证码是为了增加注册或者登录难度,减少被人用脚本疯狂登录注册导致的一系列危害,减少数据库的一些压力。 毕竟那些用脚本生成的账号都是垃圾账号 本次实践:生成这样的…...
编程探秘:Python深渊之旅-----数据可视化(八)
客户提出了对数据报告和图表的具体要求,这使得团队需要快速掌握数据可视化的技巧。派超决定深入了解 Python 中的数据可视化工具。 派超(兴奋地):我们有机会做些真正酷炫的数据报告了!我听说 Python 有很棒的图表库。…...
上海亚商投顾:创业板指冲高回落 光伏、航运股逆势走强
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 沪指1月12日冲高回落,创业板指午后跌近1%。北证50指数跌超6%,倍益康、华信永道、众诚科…...
Python3 中常用字符串函数介绍
介绍 Python 中有几个与 字符串数据类型相关的内置函数。这些函数让我们能够轻松修改和操作字符串。我们可以将函数视为在代码元素上执行的操作。内置函数是在 Python 编程语言中定义的,并且可以随时供我们使用的函数。 在本教程中,我们将介绍在 Pytho…...
Python - 深夜数据结构与算法之 AVL 树 红黑树
目录 一.引言 二.高级树的简介 1.树 2.二叉树 3.二叉搜索树 4.平衡二叉树 三.AVL 树 ◆ 插入节点 ◆ 左旋 ◆ 右旋 ◆ 左右旋 ◆ 右左旋 ◆ 一般形式 ◆ 实际操作 ◆ 总结 四.红黑树 ◆ 概念 ◆ 示例 ◆ 对比 五.总结 一.引言 前面我们介绍了二叉树、二叉…...
Zookeeper使用详解
介绍 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布…...
C#属性(Property)
文章目录 一、C#属性(Property)?二、属性的用法总结 一、C#属性(Property)? C#属性(Property)是一种访问器(accessor),用于封装一个类的字段&…...
在docker中搭建部署clickhouse
因需要给网关日志拉取并存储供数据分析师分析,由于几十个项目的网关请求数量很大,放在mysql不合适,MongoDB不适合分析,于是准备存放在clickhouse,clickhouse对于读写支持也比较友好,说干就干 1、在服务器中…...
第九部分 使用函数 (三)
目录 一、文件名操作函数 1、dir 2、notdir 3、suffix 4、basename 5、addsuffix 6、addprefix 7、join 一、文件名操作函数 下面我们要介绍的函数主要是处理文件名的。每个函数的参数字符串都会被当做一个或是 一系列的文件名来对待。 1、dir $(dir <names..>…...
基础命令继续
1:创建目录命令 mkdir命令 注意:创建文件夹需要修改权限,请确保操作均在HOME目录内,不要在Home外操作,涉及到权限问题,HOME外无法识别 小结: 练习: 2:touch创建文件 2:c…...
uni-app做A-Z排序通讯录、索引列表
上图是效果图,三个问题 访问电话通讯录,拿数据拿到用户的联系人数组对象,之后根据A-Z排序根据字母索引快速搜索 首先说数据怎么拿 - 社区有指导https://ask.dcloud.net.cn/question/64117 uniapp 调取通讯录 // #ifdef APP-PLUSplus.contac…...
Codeforces Round 768 (Div. 1) D. Flipping Range(思维题 等价类性质 dp)
题目 思路来源 官方题解 洛谷题解 题解 可操作的最短区间长度肯定是gcd,记为g,然后考虑如何dp 考虑g个等价类,每个等价类i,ig,i2*g,... 每次翻转长度为g的区间,会同时影响到g个等价类总的翻转的奇偶性, 性质一&…...
springboot集成kafka消费数据
springboot集成kafka消费数据 文章目录 springboot集成kafka消费数据1.引入pom依赖2.添加配置文件2.1.添加KafkaConsumerConfig.java2.2.添加KafkaIotCustomProperties.java2.3.添加application.yml配置 3.消费者代码 1.引入pom依赖 <dependency><groupId>org.spri…...
单例模式---JAVA
目录 “饿汉”模式 完整代码 “懒汉”模式 完整代码 单例模式:保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例。 单例模式可以通过实例创建的时间来分为两种:“饿汉”和“懒汉”模式。 “饿汉”模式 所谓的“饿汉”模式实则就是在类…...
maven管理使用
maven基本使用 一、简介二、配置文件三、项目结构maven基本标签实践(例子) 四、pom插件配置五、热部署六、maven 外部手动加载jar打包方式Maven上传私服或者本地 一、简介 基于Ant 的构建工具,Ant 有的功能Maven 都有,额外添加了其他功能.本地仓库:计算机中一个文件夹,自己定义…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
