【优选算法专栏】专题四:前缀和(二)

本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。

💓博主csdn个人主页:小小unicorn
⏩专栏分类:算法从入门到精通
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识

专题四

  • 寻找数组中心下标
    • 算法原理:
  • 除自身以外数组的乘积
    • 算法原理:

寻找数组中心下标

给你一个整数数组 nums ,请计算数组的 中心下标 。

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
在这里插入图片描述

算法原理:

分析题目,既然要找到数组中心下标,我们先假设数组中心为 i i i,那么 i i i就将数组分成两部分,只要i前面部分的和等于i后面的和,那么此时i就是数组中心,反之就没有数组中心。

前面部分的和我们是可以通过前缀和计算出来的,那么后面的和怎么算呢?其实既然前缀和计算的是前面部分的和,那么后面部分的和我们可以用后缀和来进行计算。

在这里插入图片描述

接下来我们要预处理前缀和和后缀和数组:

f[i]表示:[0,i-1]区间所有元素的和。
g[i]表示:[i+1,n-1]区间所有元素的和。

接下来递推:
在这里插入图片描述

要想算[0,i-1]区间的和,那么我们可以先算[0,i-2]区间的和再加上[i-1]本身的值。
那么也就是:
f [ i ] = f [ i − 1 ] + n u m s [ i − 1 ] f[i]=f[i-1]+nums[i-1] f[i]=f[i1]+nums[i1];
同理:
g [ i ] = g [ i + 1 ] + n u m s [ i + 1 ] g[i]=g[i+1]+nums[i+1] g[i]=g[i+1]+nums[i+1];
在这里插入图片描述
下来使用前缀和数组:
在这里插入图片描述

要想求数组中心,那么我们只用判断 f [ i ] = = g [ i ] f[i]==g[i] f[i]==g[i]即可,要是相等数组中心就是i位置,反之就是不存在。

介绍到这,原理基本上其实已经就完了,但是在写代码之前还要注意一下细节问题:

为方式越界访问

当下标为0时, f [ 0 ] = f [ − 1 ] + n u m s [ 0 ] f[0]=f[-1]+nums[0] f[0]=f[1]+nums[0];为防止这种情况,我们要让f[0]=0,不影响原始值。

同理,当下标为n-1时, g [ n − 1 ] = g [ n ] + n u m s [ n − 1 ] g[n-1]=g[n]+nums[n-1] g[n1]=g[n]+nums[n1];为防止这种情况,我们要将g[n-1]=0;
当然因为f[i]表示前缀和,因此填表顺序从左往右,相反g[i]填表顺序型右往左。

代码实现:

class Solution 
{
public:
    int pivotIndex(vector<int>& nums) 
    {
        int n=nums.size();
        vector<int> f(n),g(n);
        //1.预处理前缀和数组

        //前缀和数组
        for(int i=1;i<n;i++)
            f[i]=f[i-1]+nums[i-1];
        //后缀和数组
        for(int i=n-2;i>=0;i--)
            g[i]=g[i+1]+nums[i+1];
        //使用前缀和数组
        for(int i=0;i<n;i++)
        {
            if(f[i]==g[i])
                return i;
        }
        return -1;
    }
};

除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

请 不要使用除法,且在 O(n) 时间复杂度内完成此题。

在这里插入图片描述

算法原理:

解法一:暴力+枚举
在这里插入图片描述
我们模拟一下题目的行为,每算一个下标,通过暴力枚举的方式将乘积乘起来。但是这样时间复杂度是 O ( N 2 ) O(N ^2) O(N2)显然会超时。

解法二:前缀和

根据第一题的经验,其实这道题跟第一题基本一模一样。
还是将数组分成两部分:
在这里插入图片描述
要想计算i位置除i位置其余的乘积,i将数组分成两部分,我们将i位置之前和之后的乘积分别算出来,然后在乘起来就是最终结果。

因此还是用两个数组分别是前缀积和后缀积:

f[i]表示:从[0,i-1]区间内所有元素的乘积。
g[i]表示:从[i+1,n-1]区间内所有元素的乘积。

接下来推递推式子:
有了第一题的经验,本题式子很好推。
f [ i ] = f [ i − 1 ] ∗ n u m s [ i − 1 ] f[i]=f[i-1]*nums[i-1] f[i]=f[i1]nums[i1];
g [ i ] = g [ i + 1 ] + n u m s [ i + 1 ] g[i]=g[i+1]+nums[i+1] g[i]=g[i+1]+nums[i+1];

使用前缀和数组:
要想拿到i位置的结果,那么我们直接让我们的前缀积和后缀积相乘即可,也就是:
i->f[i]*g[i];

为防止越界,f[0]和g[n-1]要进行初始化,但是此时不能初始化为0,要初始化为1,因为要不影响结果值。

填表顺序:
f[i]:从左往右
g[i]:从右往左;

代码实现:

class Solution 
{
public:
    vector<int> productExceptSelf(vector<int>& nums) 
    {
        int n=nums.size();
        vector<int> f(n),g(n);
        vector<int> ret(n);

        f[0]=1;
        g[n-1]=1;
        //1.预处理前缀和数组
        for(int i=1;i<n;i++)
            f[i]=f[i-1]*nums[i-1];
        for(int i=n-2;i>=0;i--)
            g[i]=g[i+1]*nums[i+1];

        //2.使用前缀和数组
        for(int i=0;i<n;i++)
        {
            ret[i]=f[i]*g[i];
        }
        return ret;
    }
};

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

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

相关文章

gitee上传出现git did not exit cleanly (exit code 1)的错误

在最后push的时候出现下面的结果&#xff1a; 出现这个错误的原因有好多种&#xff0c;目前介绍博主遇到的两种&#xff1a; 在第一次进行push操作的时候&#xff0c;需要输入用户名和密码&#xff0c;如果输入错误&#xff0c;则最后可能会出现上述报错 解决方法&#xff1a;…

智慧InSAR专题———模拟数据实现现实场景异常形变点识别(项目讲解)

续上篇 文章目录 &#xff08;一项技术的复现&#xff0c;我们应该有打破砂锅问到底的态度&#xff0c;我找到了这篇文章的一些灵感来源&#xff0c;包括算法和编程以及专业知识等&#xff0c;对我而言也是受益匪浅&#xff09;1. 数据准备1.1 A deep learning approach to de…

基于STM32F103单片机的时间同步项目

一、前言 本项目为前一个时间同步项目的更迭版本,由于之前的G031开发板没有外部晶振,从机守时能力几乎没有,5秒以上不同步从机时间就开始飞了。在考虑成本选型后,选择了带有外部有缘晶振的STM32F103C8T6最小单片机,来作为本次项目的开发平台。 G031时间同步链接: 基于ST…

mui和uniapp跳转外部链接

Hbuilder开发的app&#xff0c;会涉及到跳转H5页面 mui <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content"initial-scale1.0, maximum-scale1.0, user-scalableno" /><link …

windows下安装yolov8环境(详细图文教程)

目录 一&#xff1a;前言 二&#xff1a;安装yolov8 一&#xff1a;前言 最近看了 YOLO 的发展史&#xff0c;发现在机器视觉领域的应用非常广泛&#xff0c;f刚好最近一直在做机器视觉的工作&#xff0c;特此记录下搭建yolov的环境。我们使用的版本是yolov8的就用这个作为演…

大小端、结构体对齐

目录 王道ppt总结&#xff1a;​编辑 个人理解&#xff1a; 相关文章&#xff1a; 王道ppt总结&#xff1a; 个人理解&#xff1a; 机器的读取数据的顺序&#xff1a;都是从低地址开始。 为什么&#xff1f;假如进行一个加法计算&#xff0c;肯定是从最低位开始&#xff0c…

spring eureka 服务实例实现快速下线快速感知快速刷新配置解析

背景 默认的Spring Eureka服务器&#xff0c;服务提供者和服务调用者配置不够灵敏&#xff0c;总是服务提供者在停掉很久之后&#xff0c;服务调用者很长时间并没有感知到变化。或者是服务已经注册上去了&#xff0c;但是服务调用方很长时间还是调用不到&#xff0c;发现不了这…

apline安装redisjson

安装前的说明 由于redis现在下载redisjson很繁琐&#xff0c;还可能需要科学上网&#xff0c;只能自己编译了 系统是apline&#xff0c; 为什么是这个系统&#xff1f;原因是docker安装redis是用了这个系统 下载地址,按照实际情况选择&#xff0c;如果不行就老老实实自己编译吧…

ESP8266开发

1esp8266Wifi连接,通过手机控制点灯 1.下载Arduino,编程 2.下载blinker手机APP。 3.下载blinker库。https://arduino.me/s/blinker-arduino?aid=711 4.打开编程工具 Arduino,加载blinker库 5. 打开库里面的例程,基于例程开发。 blinker-library-0.3.10230510\blinker-…

数据同步工具datax配置与示例

文章目录 前言一、部署步骤1、jdk环境2、python环境步骤一&#xff1a;安装方式一&#xff1a;官网下载安装包方式二&#xff1a;brew命令安装 步骤二&#xff1a;配置环境变量步骤三&#xff1a;验证 3、maven环境&#xff08;可选&#xff09; 二、下载安装datax1、下载datax…

C语言完结篇(17)

编译和链接 1. 翻译环境和运⾏环境 2. 翻译环境&#xff1a;预编译编译汇编链接 我们知道计算机能够执行的是二进制的指令 而我们的C语言代码都是文本信息 所以我们需要让C语言代码转变为二进制的指令&#xff08;这是需要编译器来进行处理的&#xff09; 翻译环境和运⾏…

SpringBoot启动流程分析之准备应用上下文refreshContext()

文章目录 源码入口1、准备刷新1.1、子类prepareRefresh()方法1.2 父类prepareRefresh&#xff08;&#xff09;方法 2、通知子类刷新内部bean工厂3、准备bean工厂4、允许上下文子类对bean工厂进行后置处理 源码入口 org.springframework.boot.SpringApplication#run(java.lang…

github克隆报错:failed: The TLS connection was non-properly terminated.

github克隆gazebo_ros_control报错 fatal: unable to access https://github.com/ros-controls/gazebo_ros_control.git/: gnutls_handshake() failed: The TLS connection was non-properly terminated. sudo apt-get install ros-noetic-gazebo-ros-control git 克隆gazeb…

微信小程序 django+nodejs电影院票务售票选座系统324kd

小程序Android端运行软件 微信开发者工具/hbuiderx uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 前端&#xff1a;HTML5,CSS3 VUE 后端&#xff1a;java(springbootssm)/python(flaskdja…

C/C++基础----判断和循环

判断 if-elseif-else判断 语句&#xff1a; 条件使用之前的逻辑运算符或者关系运算符 if(条件1){条件1成立时内容 }else if(条件2){条件2成立时内容 }else{所有条件不成立时内容 }#include <iostream>using namespace std;int main() {int age 10;if (age > 18) {c…

高云FPGA的管脚约束文件的复制

问&#xff1a;Gowin里面能不能直接拷贝一个管脚约束文件进去用&#xff1f; 答&#xff1a; 可以直接拷贝&#xff0c;但是拷贝前后两个工程对应的芯片必须要是同一个芯片 拷贝方法: 第一步&#xff1a;按照被拷贝约束文件对应的芯片新建一个工程&#xff0c;然后将原工程文…

最强开源多模态生成模型MM-Interleaved:特征同步器突破,多模态生成的终极解决方案

前言 在人工智能领域&#xff0c;多模态生成模型一直是探索的前沿&#xff0c;它跨越了图像与文本之间的界限&#xff0c;开启了一种全新的交互方式。最近&#xff0c;上海人工智能实验室联合香港中文大学多媒体实验室&#xff08;MMLab&#xff09;、清华大学、商汤科技和多伦…

农场大乐斗游戏演示

功能介绍 农场系统 种菜操作&#xff1a;用户可以在农场中种植农作物&#xff0c;并进行浇水、杀虫、除草等维护操作。干旱、虫害、杂草都会影响农作物的生长速度和产量。农作物成熟后&#xff0c;用户需要及时收取&#xff0c;否则会在24小时后枯死&#xff0c;但可通过观看…

java 邮件发送表格

邮件发送表格 问题导入效果图 实现方案1. 拼接HTML文件&#xff08;不推荐&#xff09;2. excel 转HTML使用工具类来转化依赖工具类代码示例 使用已工具包 如 aspose-cells依赖代码示例 3.使用模板生成流程准备模板工具类代码示例 问题导入 在一些定时任务中&#xff0c;经常会…

JavaScript - 你是如何区分一个变量是对象还是数组的

难度级别:中高级及以上 提问概率:65% 我们日常如果想要获得一个变量的类型,大多会使用typeof的方法,但typeof却不是很准确,遇到null、数组或是对象这种数据类型的时候,他就失灵了,返回值是object,那么都有哪些方式可以区分一个变量的类…