[Algorithm][前缀和][和为K的子数组][和可被K整除的子数组][连续数组][矩阵区域和]详细讲解

目录

  • 1.和为 K 的子数组
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.和可被 K 整除的子数组
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.连续数组
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 4.矩阵区域和
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.和为 K 的子数组

1.题目链接

  • 和为 K 的子数组

2.算法原理详解

  • 分析:因为有负数的存在
    • 无法使用"双指针"优化,因为区间求和不具备单调性
    • 可能已经找到前缀和为k的子数组了,但是后面仍然可能会有更长的和为k的子数组存在
  • 思路:前缀和 + 哈希表
    • 前缀和i位置为结尾的所有的子数组
      • 将问题转化为:在[0, i - 1]区间内,有多少个前缀和等于sum[i] - k
      • 此时,该连续区间问题就可以转化为一个前缀和问题了
    • 哈希表<int, int> -> <前缀和, 次数>
  • 细节处理
    • 前缀和加入哈希表的时机?
      • 由于是在[0, i - 1]区间内,找有多少个前缀和等于sum[i] - k
      • 所以在计算i位置之前,哈希表里面只保存[0, i - 1]位置的前缀和
    • 不用真的创建一个前缀和数组
      • 因为只关⼼在i位置之前,有多少个前缀和等于sum[i] - k
      • 用一个变量sum来标记前一个位置的前缀和即可
    • 如果整个前缀和等于k呢?
      • hash[0] = 1
      • 即:默认哈希表中存在一个前缀和为0的值
        请添加图片描述

3.代码实现

int SubarraySum(vector<int>& nums, int k) 
{unordered_map<int, int> hash; // <前缀和, 次数>hash[0] = 1;int ret = 0, sum = 0; // 标识前一个位置的前缀和for(auto& e : nums){sum += e; // 计算当前位置的前缀和if(hash.count(sum - k)){ret += hash[sum - k];}hash[sum]++; // 将i位置的前缀和入hash}return ret;
}

2.和可被 K 整除的子数组

1.题目链接

  • 和可被 K 整除的子数组

2.算法原理详解

  • 前置知识
    • 同余定理(a - b) / p = k -> a % p == b % p
    • C++ [ 负数 % 正数 ] [负数 \% 正数] [负数%正数]结果修正
      • 结果 [ 负数 % 正数 ] [负数 \% 正数] [负数%正数] -> 负数
        • 尽可能让商,进行向0取整
      • 修正a % p + p
      • 正负统一(a % p + p) % p
  • 分析:因为有负数的存在
    • 无法使用"双指针"优化,因为区间求和不具备单调性
    • 可能已经找到前缀和可以被k整除的子数组了,但是后面仍然可能会有更长的前缀和可以被k整除的子数组存在
  • 思路:前缀和 + 哈希表
    • 前缀和i位置为结尾的所有的子数组
      • 将问题转化为:在[0, i - 1]区间内,有多少个前缀和的余数等于(sum % k + k) % k
      • 此时,该连续区间问题就可以转化为一个前缀和问题了
    • 哈希表<int, int> -> <前缀和, 次数>
  • 细节处理
    • 前缀和加入哈希表的时机?
      • 由于是在[0, i - 1]区间内,找有多少个前缀和的余数等于(sum % k + k) % k
      • 所以在计算i位置之前,哈希表里面只保存[0, i - 1]位置的前缀和的余数
    • 不用真的创建一个前缀和数组
      • 因为只关⼼在i位置之前,有多少个前缀和的余数等于(sum % k + k) % k
      • 用一个变量sum来标记前一个位置的前缀和即可
    • 如果整个前缀和等于k呢?
      • hash[0] = 1
      • 即:默认哈希表中存在一个前缀和余数为0的值
        请添加图片描述

3.代码实现

int subarraysDivByK(vector<int>& nums, int k) 
{unordered_map<int, int> hash;// <前缀和余数, 次数>hash[0] = 1;int sum = 0, ret = 0; // 用于标记前一个位置的前缀和for(auto& e : nums){sum += e; // 计算当前位置的前缀和int tmp = (sum % k + k) % k; // 修正后的余数if(hash.count(tmp)){ret += hash[tmp];}hash[tmp]++; // 将i位置的前缀和的余数入hash}return ret;
}

3.连续数组

1.题目链接

  • 连续数组

2.算法原理详解

  • 问题转化

    • 将所有的 0 0 0修改成 − 1 -1 1
    • 在数组中,找出最长的子数组,使子数组中所有元素的和为0
  • [和为k的子数组] -> [和为0的子数组]

  • 思路:前缀和 + 哈希表

    • 前缀和i位置为结尾的所有的子数组
      • 将问题转化为:在[0, i - 1]区间内,有多少个前缀和等于sum
      • 此时,该连续区间问题就可以转化为一个前缀和问题了
    • 哈希表<int, int> -> <前缀和,下标>
      请添加图片描述
  • 细节处理

    • 前缀和加入哈希表的时机?`
      • 在计算i位置之前,哈希表里面只保存[0, i - 1]位置的前缀和
      • 所以,使用完之后,丢进哈希表
    • 如果哈希表中有重复的(sum, i),如何存?
      • 因为要找最长的子数组
      • 所以只需要保留前面的那一对(sum, i)即可
    • 不用真的创建一个前缀和数组
      • 因为只关⼼在i位置之前,有多少个前缀和等于sum
      • 用一个变量sum来标记前一个位置的前缀和即可
    • 默认的前缀和为0的情况,如何存?
      • hash[0] = -1
    • 长度怎么算?
      • i - j
        请添加图片描述

3.代码实现

int FindMaxLength(vector<int>& nums) 
{unordered_map<int, int> hash; // <前缀和, 下标>hash[0] = -1; // 默认有一个前缀和为0的情况int sum = 0, len = 0; // 标记前一次的前缀和for(int i = 0; i < nums.size(); i++){sum += nums[i] == 0 ? -1 : 1;if(hash.count(sum)){len = max(len, i - hash[sum]); // 更新最大长度}else{hash[sum] = i; // 将(sum, i)入hash}}return len;
}

4.矩阵区域和

1.题目链接

  • 矩阵区域和

2.算法原理详解

  • 该题就是对**[二维前缀和]**的一个实际应用

  • 左上角/右上角坐标可能会越界

    • 左上角:
      • x 1 = m a x ( 0 , i − k ) + 1 x_1 = max(0, i - k) + 1 x1=max(0,ik)+1
      • y 1 = m a x ( 0 , j − k ) + 1 y_1 = max(0, j - k) + 1 y1=max(0,jk)+1
    • 右下角
      • x 2 = m i n ( m − 1 , i + k ) + 1 x_2 = min(m - 1, i + k) + 1 x2=min(m1,i+k)+1
      • y 2 = m i n ( n − 1 , j + k ) + 1 y_2 = min(n - 1, j + k) + 1 y2=min(n1,j+k)+1
        请添加图片描述
  • 下标的映射关系
    请添加图片描述


3.代码实现

vector<vector<int>> MatrixBlockSum(vector<vector<int>>& mat, int k) 
{int row = mat.size(), col = mat[0].size();// 预处理前缀和数组vector<vector<int>> dp(row + 1, vector<int>(col + 1));for(int i = 1; i <= row; i++){for(int j = 1; j <= col; j++){// 下标映射关系 dp[x, y] -> mat[x - 1][y - 1]dp[i][j] = dp[i - 1][j] + dp[i][j - 1] \- dp[i - 1][j - 1] + mat[i - 1][j - 1];}}// 使用前缀和数组vector<vector<int>> ret(row, vector<int>(col));for(int i = 0; i < row; i++){for(int j = 0; j < col; j++){// 下标映射关系 ret[x][y] -> dp[x + 1][y + 1]int x1 = max(0, i - k) + 1;int y1 = max(0, j - k) + 1;int x2 = min(row - 1, i + k) + 1;int y2 = min(col - 1, j + k) + 1;ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] \- dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];}}return ret;
}

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

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

相关文章

牛客 题解

文章目录 day4_17**BC149** **简写单词**思路&#xff1a;模拟代码&#xff1a; dd爱框框思路&#xff1a;滑动窗口&#xff08;同向双指针&#xff09;代码&#xff1a; 除2&#xff01;思路&#xff1a;模拟贪心堆代码&#xff1a; day4_17 BC149 简写单词 https://www.now…

如何在 Ubuntu 14.04 上配置 StatsD 以收集 Graphite 的任意统计数据

介绍 Graphite 是一个图形库&#xff0c;允许您以灵活和强大的方式可视化不同类型的数据。它通过其他统计收集应用程序发送给它的数据进行图形化。 在之前的指南中&#xff0c;我们讨论了如何安装和配置 Graphite 本身&#xff0c;以及如何安装和配置 collectd 以编译系统和服…

【MATLAB源码-第197期】基于matlab的粒子群算法(PSO)结合人工蜂群算法(ABC)无人机联合卡车配送仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 基于粒子群优化&#xff08;PSO&#xff09;算法的无人机联合卡车配送系统是一个高效的物流配送策略&#xff0c;旨在优化配送过程中的成本、时间和资源利用率。该系统融合了无人机和卡车的配送能力&#xff0c;通过智能算法…

Tiny11作者开源:利用微软官方镜像制作独属于你的Tiny11镜像

微软对Windows 11的最低硬件要求包括至少4GB的内存、双核处理器和64GB的SSD存储。然而&#xff0c;这些基本要求仅仅能保证用户启动和运行系统&#xff0c;而非流畅使用 为了提升体验&#xff0c;不少用户选择通过精简系统来减轻硬件负担&#xff0c;我们熟知的Tiny11便是其中…

【简单介绍下机器学习之sklearn基础】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【机器学习】深度神经网络(DNN):原理、应用与代码实践

深度神经网络&#xff08;DNN&#xff09;&#xff1a;原理、应用与代码实践 一、深度神经网络&#xff08;DNN&#xff09;的基本原理二、DNN的优缺点分析三、DNN的代码实践四、总结与展望 在人工智能与机器学习的浪潮中&#xff0c;深度神经网络&#xff08;Deep Neural Netw…

演示在一台Windows主机上运行两个Mysql服务器(端口号3306 和 3307),安装步骤详解

目录 在一台Windows主机上运行两个Mysql服务器&#xff0c;安装步骤详解因为演示需要两个 MySQL 服务器终端&#xff0c;我只有一个 3306 端口号的 MySQL 服务器&#xff0c;所以需要再创建一个 3307 的。创建一个3307端口号的MySQL服务器1、复制 mysql 的安装目录2、修改my.in…

安全开发实战(4)--whois与子域名爆破

目录 安全开发专栏 前言 whois查询 子域名 子域名爆破 1.4 whois查询 方式1: 方式2: 1.5 子域名查询 方式1:子域名爆破 1.5.1 One 1.5.2 Two 方式2:其他方式 总结 安全开发专栏 安全开发实战​​http://t.csdnimg.cn/25N7H 前言 whois查询 Whois 查询是一种用…

MCU功耗测量

功耗测量 一、相关概念二、功耗的需求三、测量仪器仪表测量连接SMU功能SMU性能指标 四、功耗测量注意点板子部分存在功耗MCU方面&#xff0c;可能存在干扰项仪器仪表方面 一、相关概念 静态功耗和动态功耗&#xff1a;动态功耗为运行功耗&#xff0c;功耗测量注重每MHz下的功耗…

DevOps文化对团队有何影响?

DevOps文化对团队有很多积极影响&#xff0c;包括提高团队效率、促进沟通与协作、提高产品质量和推动创新等方面。然而&#xff0c;实施DevOps文化也需要一定的挑战&#xff0c;如改变团队成员的观念、引入新的工具和流程等。因此&#xff0c;团队需要充分了解DevOps文化的价值…

【重磅开源】MapleBoot项目开发规范

基于SpringBootVue3开发的轻量级快速开发脚手架 &#x1f341;项目简介 一个通用的前、后端项目模板 一个快速开发管理系统的项目 一个可以生成SpringBootVue代码的项目 一个持续迭代的开源项目 一个程序员的心血合集 度过严寒&#xff0c;终有春日&#xff…

计算机网络-IS-IS基础配置实验

前面我们了解了IS-IS的一些基础理论&#xff0c;从建立邻接、链路状态数据库同步以及路由计算&#xff0c;现在开始学习下配置操作。 一、IS-IS配置 网络拓扑图&#xff1a; 拓扑图 IS-IS有Level级别的区分&#xff0c;Level-1可以是性能较低的设备只维护区域内的LSDB&#xff…

《R语言与农业数据统计分析及建模》学习——描述性统计分析

一、描述性统计概念和方法 1、概念和作用 描述性统计是对数据进行概括和描述&#xff0c;便于理解数据的特征、趋势和分布&#xff0c;帮助我们了解数据基本情况和总体特征&#xff0c;为后续更深入的数据分析和建模提供基础。 2、基础方法 &#xff08;1&#xff09;中心趋…

npm、yarn与pnpm详解

&#x1f525; npm、yarn与pnpm详解 &#x1f516; 一、npm &#x1f50d; 简介&#xff1a; npm是随Node.js一起安装的官方包管理工具&#xff0c;它为开发者搭建了一个庞大的资源库&#xff0c;允许他们在这个平台上搜索、安装和管理项目所必需的各种代码库或模块。 &#…

CountDownLatch源码分析

1.创建 CountDownLatch latch new CountDownLatch(5); 2.latch.countDown(); 将count执行减一操作&#xff0c;当count为0时&#xff0c;等待中的线程会被唤醒 SIGNAL (值为-1)&#xff1a; 表示后继节点需要被唤醒。当一个节点释放锁的时候&#xff0c;会唤醒它的后继节点…

openjudge_2.5基本算法之搜索_1998:寻找Nemo

题目 1998:寻找Nemo 总时间限制: 2000ms 内存限制: 65536kB 描述 Nemo 是个顽皮的小孩. 一天他一个人跑到深海里去玩. 可是他迷路了. 于是他向父亲 Marlin 发送了求救信号.通过查找地图 Marlin 发现那片海像一个有着墙和门的迷宫.所有的墙都是平行于 X 轴或 Y 轴的. 墙的厚度可…

2010-2023年“国家级大数据综合试验区”试点城市DID匹配数据

2010-2023年国家级大数据综合试验区试点城市DID匹配数据 1、时间&#xff1a;2010-2023年 2、来源&#xff1a;国家发展改革委、工业和信息化部、ZY网信办发函批复的试验区 3、指标&#xff1a;行政区划代码、年份、所属省份、地区、国家级大数据综合试验区、最早设立年份 …

ELK创建仪表盘

创建仪表盘步骤&#xff1a; 一、保存search二、生成饼图三、创建仪表盘 一、保存search 首先保存一段时间内的search&#xff0c;可以添加想要的字段&#xff0c;并保存这个search方便下次直接打开该search&#xff0c;并方便在可视化和仪表盘中使用该search. 二、生成饼图…

c++中的函数

一、函数概述 作用&#xff1a;将一段经常使用的代码封装起来&#xff0c;减少重复代码 一个较大的程序&#xff0c;一般分为若干个程序块&#xff0c;每个程序块实现特定功能。 二、函数的定义 函数定义主要有5个步骤&#xff1a; 返回值类型函数名参数列表函数体语句ret…

Laravel 6 - 第十二章 控制器

​ 文章目录 Laravel 6 - 第一章 简介 Laravel 6 - 第二章 项目搭建 Laravel 6 - 第三章 文件夹结构 Laravel 6 - 第四章 生命周期 Laravel 6 - 第五章 控制反转和依赖注入 Laravel 6 - 第六章 服务容器 Laravel 6 - 第七章 服务提供者 Laravel 6 - 第八章 门面 Laravel 6 - …