当前位置: 首页 > news >正文

【专题四】前缀和(3)

📝前言说明:

  • 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分
  • 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话)
  • 文章中的理解仅为个人理解。如有错误,感谢纠错

🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux
🎀CSDN主页 愚润泽

视频

  • 974. 和可被 K 整除的子数组
    • 个人解
    • 优质解
  • 525. 连续数组
    • 个人解
    • 优质解
  • 1314. 矩阵区域和
    • 个人解


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

题目链接:974. 和可被 K 整除的子数组

在这里插入图片描述

个人解

思路:
和上篇文章的第三题一样,但是,因为哈希表里面可能有多个前缀和都满足要求,而我没想到如何快速搜索到这些前缀和。
暴力解法:O( n 2 n^2 n2)是过不了的。


优质解

思路:

  • 哈希表里面有多个前缀和满足要求是因为:可能出现dp[x2] = dp[x1] + k的情况(即两数之间差nk),导致对于dp[i],可能有多个前缀和与之匹配。那如何保证唯一且能把这些数全部统计到呢?
  • 我们可以在记录前缀和的时候,不记录前缀和,而是记录前缀和 % k的余数。
  • 因为:如果(dp[i] - dp[x]) % k == 0,则dp[i] % k == dp[x] % k
  • 细节问题:我们的数组中有负数,但是C++ 中的取模性质:负数 % 正数 == 负数。所以我们要对模出来的结果进行修正
  • 修正:对于负数结果修正:余数 = dp[i] % k + k,但是为了正负数同一:余数 = (dp[i] % k + k) % k

代码:

class Solution {
public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int, int> hash;int ans = 0, sum = 0;hash[0] = 1;for(auto x: nums){sum += x; // sum代表当前位置的前缀和int modulus = (sum % k + k) % k;if(hash.count(modulus)) ans += hash[modulus];hash[modulus]++;}return ans;}
};

时间复杂度:O( n n n)
空间复杂度:O( n n n)


525. 连续数组

题目链接:525. 连续数组

在这里插入图片描述

个人解

思路:
脑子锈了,只能想到O( n 2 n^2 n2)的解法。


优质解

思路:

  • 0-1
  • 问题变成:找子数组所有元素和为0的最长子数组。
  • 细节1:哈希表存储什么? 答:<前缀和,下标>,并且如果遇到相同的前缀和,下标大的不存(因为子数组短)
  • 细节2:当前位置的信息使用完以后才存入哈希表,不然dp[i] - dp[i]这个子数组实际为空
  • 细节3:默认前缀和0的位置要存在-1

代码:

class Solution {
public:int findMaxLength(vector<int>& nums) {int ans = 0, sum = 0;unordered_map<int, int> hash;hash[0] = -1;for(int i = 0; i < nums.size(); i++){sum += (nums[i] == 0? -1 : 1);if(hash.count(sum)) ans = max(ans, i - hash[sum]);elsehash[sum] = i;}return ans;}
};

时间复杂度:O(n)
空间复杂度:O(n)


1314. 矩阵区域和

题目链接:1314. 矩阵区域和

在这里插入图片描述

个人解

这道题和文章中第二题很像,这道题麻烦在下标对应。
思路:

  • 题意:answer中每一格表示的是:以mat[r][c]为中心的,边长为2k+1的正方形中所有元素(且在mat中)的和
  • 建立一个二维前缀和数组:dp[i][j]代表mat[0, 0][i, j]这个矩阵内的元素和
  • 然后利用这个前缀和数组来填写answer
  • 下标对应:初始化时:因为mat的元素是从下标[0, 0]开始的,所以dp[i][j]加的应该是mat[i - 1][j - 1]
  • 使用时:dp[1][1]才对应mat的第一个元素,所以,在使用dp的时候下标都要-1

用时:20:00
屎山代码:

class Solution {
public:vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {int m = mat.size(), n = mat[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));vector<vector<int>> answer(m, vector<int>(n, 0));// 初始化前缀和数组for(int i = 1; i <= m; i++){for(int j = 1; j <= n; j++)dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + mat[i - 1][j - 1];}for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){int x1 = max(0, i - k);int y1 = max(0, j - k);int x2 = min(m - 1, i + k);int y2 = min(n - 1, j + k);answer[i][j] = dp[x2 + 1][y2 + 1] - dp[x1][y2 + 1] - dp[x2 + 1][y1] + dp[x1][y1];}}return answer;}
};

时间复杂度:O( m ∗ n m*n mn)
空间复杂度:O( m ∗ n m*n mn)


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

相关文章:

  • 升级Xcode16,flutter项目报错
  • 实现分页的几种方法
  • Field访问对象int字段,对象访问int字段,通过openjdk17 C++源码看对象字段访问原理
  • 97AB-ASEMI机器人功率器件专用97AB
  • 模型上下文协议(MCP)深度解析:大模型从“思考者“进化为“行动者“
  • 01 C++概述
  • 2025 SAP专精特新企业高峰论坛 | 工博科技以SAP公有云+AI赋能新质生产力​
  • 15、项目搭建:绘制城堡蓝图——React 19 工程配置
  • 在android 系统上qnn sdk转换,运行模型示例
  • Shell脚本-嵌套循环应用案例
  • 塔能科技:点亮节能之光,赋能工厂与城市
  • 013几何数学——算法备赛
  • 科技助力防灾减灾:卫星电话走进应急救援队伍
  • Python创意爱心代码分享指南
  • ​LangChain、LlamaIndex、MCP、Spring AI、Ollama​ 和 ​DeepSeek​ 的定义、关系及典型架构设计
  • 完美解决.NET Framework 4.0 中 System.Drawing 库不支持 WebP 格式的图像处理
  • Docker 获取 Python 镜像操作指南
  • Dots:动态实现GPUECSAnimationBaker的受击变红效果
  • 不同参数大小的DeepSeekR1模型对Java中new FileInputStream(“test.txt“).seek(100);语法错误的检查
  • WPF之Button控件详解
  • 国家统计局:一季度全国规模以上文化及相关产业企业营业收入增长6.2%
  • 葡萄牙、西班牙突发大范围停电,交通和通信服务受到严重影响
  • 杭州银行一季度净赚超60亿增逾17%,增速较去年同期有所回落
  • 深圳一季度GDP为8950.49亿元,同比增长5.2%
  • 国家卫健委:工作相关肌肉骨骼疾病、精神和行为障碍成职业健康新挑战
  • 央行副行长:我们在研究丰富政策工具箱,将适时推出增量政策