基础算法---前缀和

文章目录

  • 基本思想
  • 1.前缀和
  • 2.子矩阵的和
  • 3.长度最小的子数组
  • 4,除自身以外数组的乘积
  • 总结

在这里插入图片描述

基本思想

前缀和数组就是一个数组的前i项和
在这里插入图片描述
在这里插入图片描述
前缀和的用处:前缀和数组求出来之后我们就可以就可以求数组中的某个特定区间的和
在这里插入图片描述
就比如说求l到R的和,我们可以转换为求1到R的和减去1到l-1的和

接下来我们来做两道题,让大家感受一下

1.前缀和

这道题是一道非常经典最能代表前缀和算法的一道题

在这里插入图片描述

这道题的思路很简单就是根据公式s[i]=s[i-1]+a[i]然后将前缀和求出来,根据条件去输出,我们来看一下代码

#include<iostream>
using namespace std;
#define N 100010
//n个数据和m行
int n,m;
//定义一个数组和一个前缀和数组
int a[N],S[N];
//定义两个边界
int l,r;
int main()
{
	//输入
    cin>>n>>m;
    //输入
    for(int i=1;i<=n;i++)cin>>a[i];
    //将前缀和的s[0]定义为0,这样方便求出第多少到第多少的和
    S[0]=0;
    //根据公式求出前缀和
    for(int i=1;i<=n;i++)
    {
        S[i]=S[i-1]+a[i];
    }
    //根绝条件输出
    while(m)
    {
        cin>>l>>r;
        cout<<S[r]-S[l-1]<<endl;
        m--;
    }
    return 0;
}

2.子矩阵的和

在这里插入图片描述

这道题是二维的前缀和,我们先来讨论一下二维数组的前缀和的基本概念

对于二维数组的前缀和我们先看下图颜色标出的方块的区间
在这里插入图片描述

上面这个蓝色的区域就是二维数组的前缀和,这下我们来讨论我们该怎么求这个前缀和
在这里插入图片描述
深色区域就表示S[i-1,j]
在这里插入图片描述
紫色区域是S[i,j-1],从上图不难看出中间的四个方形的区域被重复加了两次,意思说我们还要减去中间的四个方形的区域
在这里插入图片描述
减去黑色区域,加上红色区域最后就得到了前缀和
**公式:S[i,j]=S[i-1,j]+S[i,j-1]-S[i-1,j-1]+a[i,j]

那么下面的阴影区域怎么求呢?
在这里插入图片描述
我们可以先求S[x1,y1]
减去紫色区域
在这里插入图片描述

再减去深蓝色区域
在这里插入图片描述
因为左上角的深蓝色区域被减了两次,所以需要加上,最后便得到了原来的浅蓝色区域
公式:S=S[x1,y1]-S[x2-1,y1]-S[x1,y2-1]+S[x2-1,y2-1]


接下来我们直接来做上面的子矩阵的和,根据上面的公式可以直接写出代码

#include<iostream>
using namespace std;
#define N 1010
int n,m,q;
int a[N][N],s[N][N];

int main()
{
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
        }
    }
    while(q--)
    {
        int x1,x2,y1,y2;
        cin>>x1>>y1>>x2>>y2;
        cout<<s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]<<endl;
    }
    return 0;
}

3.长度最小的子数组

在这里插入图片描述

根据题目描述,我们可以先求出前缀和,然后用滑动窗口去更新每一次的最小的长度

int minSubArrayLen(int target, int* nums, int numsSize) {
    int *S=(int*)malloc(sizeof(int)*(numsSize+1));
    S[0] = 0;
    for (int i = 1;i <= numsSize;i++)
    {
        S[i] = S[i - 1] + nums[i - 1];
    }
    int min = 0;
    int l = 0;
    int r = 1;
    while (r < numsSize + 1)
    {
        if (l == r)
        {
            if (S[l] >= target)
            {
                if (min > l || min == 0)
                    min = l;
            }
            r++;
        }
        else
        {
            if (S[r] - S[l] >= target)
            {
                if (min > r - l || min == 0)
                {
                    min = r - l;
                }
                l++;
            }
            else {
                r++;
            }
        }
    }

    return min;
}

4,除自身以外数组的乘积

在这里插入图片描述

这道题需要排除特殊情况,特殊情况就是0,遇到零我们直接跳过,然后求出累乘,求出累乘之后,再开辟一个数组,用这个数组去存储除自身以外的所有数的乘积,首先我们需要记录一下零的个数,如果零的个数超过两个的话,数组中所有的数都会被置为零,当只有一个零的时候,除了零之外的数都是0,0对应的乘积就是剩下的数的乘积
代码展示

int* productExceptSelf(int* nums, int numsSize, int* returnSize) {
    //累乘
    int sum = 1;
    //记录零的个数
    int count = 0;
    for (int i = 0;i < numsSize;i++)
    {
        //不等于0就乘到累乘中
        if (nums[i] != 0)
        {
            sum *= nums[i];
        }
        //如果是0就count++
        if (nums[i] == 0)
        {
            count++;
        }
    }
    //将*returnSize的大小用数组大小赋值
    *returnSize = numsSize;
    //创建空间
    int* newnode = (int*)malloc(sizeof(int) * (*returnSize));
    if (count >= 2)
    {
        for (int i = 0;i < (*returnSize);i++)
        {
            newnode[i] = 0;
        }
    }
    else if (count == 0)
    {
        for (int i = 0;i < (*returnSize);i++)
        {
            newnode[i] = sum / nums[i];
        }
    }
    else
    {
        for (int i = 0;i < (*returnSize);i++)
        {
            if (nums[i] == 0)
            {
                newnode[i] = sum;
            }
            else
            {
                newnode[i] = 0;
            }
        }
    }
    return newnode;
}

总结

在本文中,我们深入探讨了前缀和算法的原理、应用以及实现方式。通过对前缀和的定义和性质的理解,我们可以更有效地解决一系列问题,特别是那些涉及连续子数组和区间求和的场景。通过将原始数据预处理成前缀和数组,我们能够在常数时间内快速地回答各种查询,从而大大提高了算法的效率。

我们讨论了如何应用前缀和算法解决了几个实际问题,例如求解子数组和的最大值、最小值,以及计算区间和等。这些问题在实际应用中经常遇到,而前缀和算法为我们提供了一种高效的解决方案。

此外,我们还介绍了如何通过巧妙地利用前缀和数组,解决了一些其他类型的问题,例如寻找具有特定和值的子数组个数、寻找具有特定和值的子数组的起始位置等。

总的来说,前缀和算法是一种非常强大且实用的技术,可以广泛应用于解决各种问题,包括算法竞赛、编程面试以及实际工程项目中。通过深入理解前缀和算法的原理和应用,我们可以在算法设计和问题求解中发挥更大的作用,提高代码的效率和性能。希望本文对读者对前缀和算法有所启发,并能够在实践中加以运用。

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

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

相关文章

linux休眠唤醒流程,及示例分析

休眠流程 应用层通过echo mem > /sys/power/state写入休眠状态&#xff0c;给一张大概流程图 这个操作对应在kernel/power/main.c的state这个attr的store操作 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t n) …

网站想实现HTTPS访问需要有哪些步骤?

网站要实现HTTPS访问&#xff0c;以确保数据传输安全和提升用户信任度&#xff0c;主要需按以下步骤操作&#xff1a; 1. 购买或申请SSL证书&#xff1a; - 根据网站类型和需求&#xff0c;选择合适的SSL证书&#xff1a;DV&#xff08;域名验证&#xff09;、OV&#xff08;组…

Maxwell安装使用和简单案例

一、解压 cd /opt/software/ ​ tar -zxvf maxwell-1.29.2.tar.gz -C /opt/module/ ​ cd /opt/module/ 二、MySQL 环境准备 1、修改 mysql 的配置文件 修改 mysql 的配置文件&#xff0c;开启 MySQL Binlog 设置 vi /etc/my.cnf 添加以下内容 server_id1 log-binmysql-…

冈萨雷斯数字图像处理资源(课后习题答案+代码+图片)

冈萨雷斯数字图像处理相关资源整理&#xff0c;资源全部来源互联网&#xff0c;方便大家下载 冈萨雷斯数字图像处理相关资源整理 课后习题 冈萨雷斯数字图像处理源代码

etcd campaign

1. 引言 本文主要讲解使用etcd进行选举的流程&#xff0c;以及对应的缺陷和使用场景 2. etcd选举流程 流程如以代码所示&#xff0c;流程为&#xff1a; clientv3.New 创建client与etcd server建立连接 concurrency.NewSession 创建选举的session&#xff0c;一般会配置ses…

微信小程序一到六章总结

第一章总结 认识微信小程序 小程序简介 微信(WeChat) 是腾讯公司于2011年1月21 日推出的一款为智能终端提供即时通信服务的应用程序。 小程序、订阅号、服务号、企业微信&#xff08;企业号&#xff09;属于微信公众平台的四大生态体系&#xff0c;它们面向不同的用户群体&…

Harmony OS应用开发性能优化全面指南

优化应用性能对于应用开发至关重要。通过高性能编程、减少丢帧卡顿、提升应用启动和响应速度&#xff0c;可以有效提升用户体验。本文将介绍一些优化应用性能的方法&#xff0c;以及常用的性能调优工具。 ArkTS高性能编程 为了提升代码执行速度&#xff0c;进而提升应用整体性…

若依如何去掉“正在加载系统资源,请耐心等待”

最近有网友反馈这个加载动画很丑&#xff0c;问我如何去掉&#xff1a; 首先找到前端页面的index.html文件&#xff0c;去掉或注释掉如下代码&#xff1a;

使用Gitee进行社交登录的流程

使用Gitee进行社交登录 创建Gitee第三方应用流程&#xff1a; 鼠标移动到个人头像上&#xff0c;点击账号设置 点击账号设置&#xff0c;选择左边目录下数据管理的第三方应用 然后选择创建应用 根据要求填写 填写好了上面的要求之后&#xff0c;点击创建应用&#xff0c;这样&…

【Java】如何获取客户端IP地址

在项目中往往涉及到“获取客户端IP地址”&#xff0c;常见到下面这样子的代码&#xff1a; package com.utils;import cn.hutool.core.util.StrUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.server.reactive.ServerHttpRequest; import java.net…

前端JS必用工具【js-tool-big-box】,获取浏览器参数、cookie、localStorage的存取

这一小节&#xff0c;我们针对js-tool-big-box工具做一些使用讲解&#xff0c;主要获取浏览器参数、cookie、localStorage的存取方面的。 这些方法差不多每次项目中要么用不到&#xff0c;要么就自己写一份&#xff0c;轮子造的很重复啊&#xff0c;而且localStorage有时候要求…

牛客网:环形链表的约瑟夫问题

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;每日一练 &#x1f337;追光的人&#xff0c;终会万丈光芒 目录 &#x1f3dd;1.问题描述&#xff1a; &#x1f3dd;2.实现代码&#xff1a; &#x1f3dd;1.问题描述&#xff1a; 前言&am…

windows系统CUDA的详细安装教程

CUDA系列 文章目录 CUDA系列前言一、CUDA简介二、安装配置视频教程三、CUDA的下载及安装3.1 环境检查3.2 CUDA 安装包下载3.3 安装CUDA&#xff08;略&#xff09;3.4 验证CUDA是否安装成功 四、cuDNN的下载及安装4.1 cuDNN下载4.2 cuDNN配置 五、配置环境变量六、下载并配置zl…

springboot 集成 i18n实现国际化信息返回 实现中英文切换 实现网站支持多语言切换

还是直接上代码 目前实现了 中英文 返回 别的语言 都差不多 主要用spring boot 自带的 类实现的 不用引入任何 依赖 使用的就是下面的类 org.springframework.context.MessageSource 是 Spring Framework 中用于支持国际化&#xff08;Internationalization&#xff0c;简称 i…

把 WordPress 变成 BaaS 服务:API 调用指南

有了前面两篇内容的铺垫&#xff0c;我们来聊聊 WordPress 作为 CMS / BaaS 服务使用时绕不开的问题&#xff0c;API 调用。 这篇内容同样的&#xff0c;会尽量少贴代码&#xff0c;简单的讲清楚一件事&#xff0c;降低阅读负担。 写在前面 首先&#xff0c;我们需要进行清晰…

使用autocannon和0x对网站进行性能分析(node)

npm i autocannon -g autocannon -c 100 -d 5 -p 10 http://localhost:3000/ 0x -o app.js 火焰图是根据程序的栈的状态对出现函数的采样数据统计而得&#xff0c;宽度代表函数运行一次所需的时长、高度代表栈的层数、颜色深度代表函数在采样中出现的频率&#xff0c;因此宽度…

手摸手教你把Ingress Nginx集成进Skywalking

背景 在微服务大行其道的今天&#xff0c;如何观测众多微服务、快速理清服务间的依赖、如何对服务之间的调用性能进行衡量&#xff0c;成了摆在大家面前的难题。对此&#xff0c;Skywalking应运而生&#xff0c;它是托管在 Apache 基金会下的开源项目&#xff0c;旨在帮助开发…

vue element-ui 表格横向滚动条在合计项下方

目前效果 需求效果 1.隐藏bodyWrapper滚动条&#xff0c;显示footerWrapper滚动条 css代码如下&#xff1a; div ::v-deep .el-table--scrollable-x .el-table__body-wrapper{overflow-x: hidden!important;z-index: 2!important;} div ::v-deep .el-table__footer-wrapper …

git的安装与配置教程--超详细版

一、git的安装 1. 官网下载git git官网地址&#xff1a;https://git-scm.com/download/win/ 选择需要的版本进行下载 2、下载完成之后&#xff0c;双击下载好的exe文件进行安装。 3、默认是C盘&#xff0c;推荐修改一下路径&#xff0c;然后点击下一步 4、Git配置&#xff…

电子邮箱是什么?电子邮箱怎么申请注册?

虽然通过电子邮箱收发邮件办公已经成为常态&#xff0c;但是很多人不清楚电子邮箱是什么&#xff1f;电子邮箱是指通过网络传递的“邮局”&#xff0c;可以用来收发电子邮件。每个人的电子邮箱地址都是唯一的&#xff0c;确保他人的邮件能准确送到我们的电子邮箱之中。电子邮箱…