leetcode238:除自身以外数组的乘积

文章目录

  • 1.使用除法(违背题意)
  • 2.左右乘积列表
  • 3.空间复杂度为O(1)的方法

在leetcode上刷到了这一题,一开始并没有想到好的解题思路,写篇博客再来梳理一下吧。
在这里插入图片描述

在这里插入图片描述
题目要求:

  • 不使用除法
  • 在O(n)时间复杂度内

1.使用除法(违背题意)

该方法分以下几步:

  1. 先遍历数组,求数组所有元素的乘积sum
  2. 再遍历一遍数组,使用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),输出数组不算进空间复杂度中,因此我们只需要常数的空间存放变量。

目前想到的方法就这些,后续想到会补充。

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

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

相关文章

新一代数字原住民:市场痛点与“繁”思维应对之道

随着科技的迅速发展&#xff0c;尤其是互联网的普及&#xff0c;新一代数字原住民经营者已经逐渐成为市场的主力军。不同于传统的消费者&#xff0c;有着独特的消费习惯和心理需求。企业要在这激烈的市场竞争中获得优势&#xff0c;深入了解这一群体的特征和心理、行为&#xf…

有趣的事,讲给有趣的人听

哈哈哈&#xff0c;今天不写技术了&#xff0c;今天分享一下生活&#xff0c;技术我们什么时候都可以学&#xff0c;但是生活更值得我们现在就去更好的体验&#xff01; 两年多的涤生大数据&#xff0c;认识了形形色色的小伙伴&#xff0c;陆续沟通下来6000多人&#xff0c;彼时…

数据库锁表原因、排查、解决

一.场景 场景1场景2二.原因三.排查四.解决方案 一.场景 场景1 锁表通常发生在DML&#xff08; insert 、update 、delete &#xff09; A操作进行全量数据同步&#xff0c;对整个表的粒度进行上锁&#xff0c;导致B操作只能等待A操作完成才能进入插入数据。此时就出现了锁表…

Elasticsearch windows开箱即用【记录】

一、准备工作 安装ES之前要在本机安装好JDK&#xff0c;对应的兼容性见官网链接&#xff1a;https://www.elastic.co/cn/support/matrix ES官网链接&#xff1a;https://www.elastic.co/cn/, 我本机安装的是JDK8&#xff0c;测试使用的是7.3.0版本的ES和Kibana。 1、首先去…

PyTorch项目源码学习(3)——Module类初步学习

torch.nn.Module Module类是用户使用torch来自定义网络模型的基础&#xff0c;Module的设计要求包括低耦合性&#xff0c;高模块化等等。一般来说&#xff0c;计算图上所有的子图都可以是Module的子类&#xff0c;包括卷积&#xff0c;激活函数&#xff0c;损失函数节点以及相…

完成源示例

本主题演示如何创作和使用自己的完成源类&#xff0c;类似于 .NET 的 TaskCompletionSource。 completion_source 示例的源代码 下面的列表中的代码作为示例提供。 其目的是说明如何编写自己的版本。 例如&#xff0c;支持取消和错误传播不在此示例的范围内。 #include <w…

VR全景技术如何应用在城市发展,助力城市宣传展示

引言&#xff1a; 随着科技的不断发展&#xff0c;VR全景技术正逐渐渗透到各行各业&#xff0c;其中较为广泛的应用之一便是城市展示。那么VR全景技术如何运用在城市展示领域&#xff0c;这项技术给城市发展带来了哪些好处&#xff1f; 一. VR全景技术简介 1.什么是VR全景技术…

怎样制作一本旅游电子相册呢?

​随着数码技术的发展&#xff0c;旅游电子相册已成为越来越多旅游爱好者的必备工具。它不仅能让您随时随地欣赏自己的旅行回忆&#xff0c;还能分享给亲朋好友&#xff0c;甚至上传到社交媒体上&#xff0c;让更多人了解您的旅行故事。那么&#xff0c;如何制作一本精美的旅游…

Postman接口测试之断言,全网最细教程没有之一!

一、断言 在 postman 中我们是在Tests标签中编写断言&#xff0c;同时右侧封装了常用的断言&#xff0c;当然 Tests 除了可以作为断言&#xff0c;还可以当做后置处理器来编写一些后置处理代码&#xff0c;经常应用于&#xff1a; 【1】获取当前接口的响应&#xff0c;传递给…

【数据开发】BI数据报表之数据可测试性设计与分析

文章目录 1、什么是BI&数据报表2、什么是可测试性3、数据测试与方法3.1 数据准确性与对比&#xff08;重要&#xff09;3.2 数据安全性 1、什么是BI&数据报表 数据报表是一种数据可视化工具 用于将数据以图表、表格和其他可视化形式呈现出来&#xff0c;以便用户可以…

BRC20通证的深度科普:它的潜力与如何导入到bitget

​BRC-20通证是什么&#xff1f; BRC-20通证&#xff1a;比特币上的“变形金刚”&#xff1f;&#xff01;不依赖智能合约&#xff0c;它们就像拥有超能力的外星人&#xff0c;直接在比特币的最小单位——聪上刻写JSON代码。哈哈&#xff0c;这比把房子建在乐高积木上还要刺激…

逆水行舟 不进则退

目录 一、前言 二、2023年度总结 三、2024展望未来 一、前言 这是我从工作以来到现在最喜欢的一句话&#xff0c;我想把这句话送给自己也想送给大家。 2019年7月实习到现在已经过去了四年多&#xff0c;进入2024年也迎来了我工作生涯的第五个年头。 在这个行业里&#xff…

Docker五部曲之四:Docker Compose

文章目录 前言Compose应用程序模型Compose规范顶层属性servicenetworkvolumesconfigssecrets 环境变量.env文件environment属性主机shell中的环境变量 Profiles&#xff08;剖面&#xff09;启动剖面自动启动剖面和依赖项解析 多compose.yml文件共享与扩展构建规范构建属性 部署…

网站后台拿Webshell

通过注入或者其他途径&#xff0c;获取网站管理员账号和密码后&#xff0c;找到后台登录地址&#xff0c;登录后&#xff0c;寻找后台漏洞上传网页后门&#xff0c;获取网站的webshell webshell的作用是方便攻击者&#xff0c;webshel是拥有fso权限&#xff0c;根据fso权限的不…

论文阅读:Bayesian GAN

Bayesian GAN 点击访问paper 官方github 半监督学习对比算法 1.简介 贝叶斯 GAN&#xff08;Saatchi 和 Wilson&#xff0c;2017&#xff09;是生成对抗网络&#xff08;Goodfellow&#xff0c;2014&#xff09;的贝叶斯公式&#xff0c;我们在其中学习生成器参数 θ g \th…

mybatisplus(service CRUD 接口)

一、我们在控制器层都是调用Service层&#xff0c;不会直接调用仓储层。现在我给大家介绍一下怎么快速实现Service 的CRUD 定义接口&#xff1a;IProductService 继承IService<实体> package com.saas.plusdemo;import com.baomidou.mybatisplus.extension.service.ISe…

Bootsrap-导航、栅格、及使用案例

文章目录 一、下载并导入Bootstrap中文文档二、Bootstrap初体验三、Boostrap导航栏四、Boostrap栅格五、博客案例六、用户登录界面七、后台管理界面八、引入图标九、Bootstrap动态效果 一、下载并导入Bootstrap中文文档 二、Bootstrap初体验 实现提交按钮&#xff0c;去中文文…

SpringBoot 入门 SpringBoot 与其他项目整合 集成 Druid 数据库连接池 集成 Log 日志 配置修改

目录 1.SpringBoot简介 1.1.什么是SpringBoot 1.2.特点 2.SpringBoot快速入门 2.1.创建SpringBoot项目 2.2.项目目录介绍 2.3.配置修改 2.4.启动SpringBoot 3.SpringBoot与其他项目整合 3.1.整合JDBC 3.2.整合Druid数据库连接池 3.3.整合MyBatis 3.4.整合Log日志 …

科研绘图(四)火山图

火山图是生物信息学中常用的一种图表&#xff0c;用来显示基因表达数据的变化。它通常将每个点表示为一个基因&#xff0c;x轴显示对数比率&#xff08;log ratio&#xff09;&#xff0c;表示基因表达的变化大小&#xff1b;y轴显示-log10(p-value)&#xff0c;表示变化的统计…