算法思想之前綴和(二)

歡迎拜訪:霧里看山-CSDN博客
本篇主題:算法思想之前綴和(二)
發布時間:2025.4.11
隸屬專欄:算法

在這里插入圖片描述

目錄

  • 滑動窗口算法介紹
    • 核心思想
    • 大致步驟
  • 例題
    • 和為 K 的子數組
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現
    • 和可被 K 整除的子數組
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現
    • 連續數組
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現
    • 矩陣區域和
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現

滑動窗口算法介紹

核心思想

前綴和(Prefix Sum) 是一種預處理數組的方法,通過預先計算并存儲數組的累積和,將區間和查詢的時間復雜度從 O(n) 優化至 O(1),適用于頻繁查詢子數組和的場景。

大致步驟

  1. 預處理出來一個前綴和數組
  2. 使用前綴和數組
  3. 處理邊界情況

例題

和為 K 的子數組

題目鏈接

560. 和為 K 的子數組

題目描述

給你一個整數數組 nums 和一個整數 k ,請你統計并返回 該數組中和為 k 的子數組的個數 。

子數組是數組中元素的連續非空序列。

示例 1

輸入:nums = [1,1,1], k = 2
輸出:2

示例 2

輸入:nums = [1,2,3], k = 3
輸出:2

提示:

  • 1 <= nums.length <= 2 * 104
  • -1000 <= nums[i] <= 1000
  • -107 <= k <= 107

算法思路

i 為數組中的任意位置,用 sum[i] 表示 [0, i] 區間內所有元素的和。
想知道有多少個i 為結尾的和為 k 的子數組,就要找到有多少個起始位置為 x1, x2, x3... 使得 [x, i] 區間內的所有元素的和為 k 。那么 [0, x] 區間內的和是不是就是sum[i] - k 了。于是問題就變成:

  • 找到在 [0, i - 1] 區間內,有多少前綴和等于 sum[i] - k 的即可。

我們不用真的初始化一個前綴和數組,因為我們只關心在 i 位置之前,有多少個前綴和等于sum[i] - k 。因此,我們僅需用一個哈希表,一邊求當前位置的前綴和,一邊存下之前每一種前綴和出現的次數。

代碼實現

class Solution {
public:int subarraySum(vector<int>& nums, int k) {unordered_map<int, int> hash;hash[0] = 1;int n = nums.size(), sum = 0, ret = 0;for(int i = 0; i < n; i++){sum += nums[i];if(hash[sum-k] > 0)ret += hash[sum-k];hash[sum]++;}return ret;}
};

在這里插入圖片描述

和可被 K 整除的子數組

題目鏈接

974. 和可被 K 整除的子數組

題目描述

給定一個整數數組 nums 和一個整數 k ,返回其中元素之和可被 k 整除的非空 子數組 的數目。

子數組 是數組中 連續 的部分。

示例 1

輸入:nums = [4,5,0,-2,-3,1], k = 5
輸出:7
解釋
有 7 個子數組滿足其元素之和可被 k = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]

示例 2:

輸入: nums = [5], k = 9
輸出: 0

提示:

  • 1 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • 2 <= k <= 104

算法思路

補充兩個小知識

  • 同余定理
    如果 (a - b) % n == 0,那么我們可以得到一個結論: a % n == b % n 。用文字敘述就是,如果兩個數相減的差能被 n 整除,那么這兩個數對 n 取模的結果相同。
    例如:(26 - 2) % 12 == 0 ,那么 26 % 12 == 2 % 12 == 2
  • c++ 中負數取模的結果,以及如何修正負數取模的結果
    • c++ 中關于負數的取模運算,結果是把負數當成正數,取模之后的結果加上一個負號
      例如: -1 % 3 = -(1 % 3) = -1
    • 因為有負數,為了防止發生出現負數的結果,以 (a % n + n) % n 的形式輸出保證為正。
      例如: -1 % 3 = (-1 % 3 + 3) % 3 = 2

設 i 為數組中的任意位置,用 sum[i] 表示 [0, i] 區間內所有元素的和。

  • 想知道有多少個i 為結尾的可被 k 整除的子數組,就要找到有多少個起始位置為 x1, x2, x3... 使得 [x, i] 區間內的所有元素的和可被 k 整除。
  • [0, x - 1] 區間內所有元素之和等于 a[0, i] 區間內所有元素的和等于 b ,可得(b - a) % k == 0
  • 由同余定理可得, [0, x - 1] 區間與 [0, i] 區間內的前綴和同余。于是問題就變成:
    • 找到在 [0, i - 1] 區間內,有多少前綴和的余數等于 sum[i] % k 的即可。

我們不用真的初始化一個前綴和數組,因為我們只關心在 i 位置之前,有多少個前綴和等于sum[i] - k 。因此,我們僅需用一個哈希表,一邊求當前位置的前綴和,一邊存下之前每一種前綴和出現的次數。

代碼實現

class Solution {
public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int, int> hash;hash[0%k] = 1;int sum = 0, ret = 0;for(auto &n : nums){sum += n;int r = (sum%k + k)%k;if(hash[r] > 0)ret+=hash[r];hash[r]++;} return ret;}
};

在這里插入圖片描述

連續數組

題目鏈接

525. 連續數組

題目描述

給定一個二進制數組 nums , 找到含有相同數量的 01 的最長連續子數組,并返回該子數組的長度。

示例 1
輸入:nums = [0,1]
輸出:2
說明:[0, 1] 是具有相同數量 0 和 1 的最長連續子數組。

示例 2

輸入:nums = [0,1,0]
輸出:2
說明:[0, 1] (或 [1, 0]) 是具有相同數量 0 和 1 的最長連續子數組。

示例 3:

輸入:nums = [0,1,1,1,1,1,0,0,0]
輸出:6
解釋:[1,1,1,0,0,0] 是具有相同數量 0 和 1 的最長連續子數組。
提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1

算法思路

稍微轉化一下題目,就會變成我們熟悉的題:

  • 本題讓我們找出一段連續的區間, 01 出現的次數相同。
  • 如果將 0 記為 -11 記為 1 ,問題就變成了找出一段區間,這段區間的和等于 0
    ? 于是,就和 560. 和為 K 的子數組 這道題的思路一樣

代碼實現

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

在這里插入圖片描述

矩陣區域和

題目鏈接

1314. 矩陣區域和

題目描述

給你一個 m x n 的矩陣 mat 和一個整數 k ,請你返回一個矩陣 answer ,其中每個 answer[i][j] 是所有滿足下述條件的元素 mat[r][c] 的和:

  • i - k <= r <= i + k,
  • j - k <= c <= j + k
  • (r, c) 在矩陣內。

示例 1

輸入:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 1
輸出:[[12,21,16],[27,45,33],[24,39,28]]

示例 2

輸入:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 2
輸出:[[45,45,45],[45,45,45],[45,45,45]]

提示

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n, k <= 100
  • 1 <= mat[i][j] <= 100

算法思路

?維前綴和的簡單應用題,關鍵就是我們在填寫結果矩陣的時候,要找到原矩陣對應區域的左上角以及右下角的坐標(推薦畫圖)

  • 左上角坐標: x1 = i - ky1 = j - k ,但是由于會超過矩陣的范圍,因此需要對 0取一個 max 。因此修正后的坐標為: x1 = max(0, i - k), y1 = max(0, j - k) ;
  • 右下角坐標: x1 = i + ky1 = j + k ,但是由于會超過矩陣的范圍,因此需要對 row - 1 ,以及 col - 1 取?個 min 。因此修正后的坐標為: x2 = min(row - 1, i + k), y2 = min(col - 1, j + k)

然后將求出來的坐標代入到二維前綴和矩陣的計算公式上即可~(但是要注意下標的映射關系)

代碼實現

class Solution {
public: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[i][j] = dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+mat[i-1][j-1];vector<vector<int>> answer(row, vector<int>(col));for(int i = 0; i < row; i++)for(int j = 0; j < col; j++){int x1 = max(0, i-k)+1, y1 = max(0, j-k)+1;int x2 = min(row-1, i+k)+1, y2 = min(col-1, j+k)+1;answer[i][j] = dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1];}return answer;}
};

在這里插入圖片描述

?? 寫在最后:以上內容是我在學習以后得一些總結和概括,如有錯誤或者需要補充的地方歡迎各位大佬評論或者私信我交流!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76590.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76590.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76590.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開源的7B參數OCR視覺大模型:RolmOCR

1. 背景介紹 早些時候&#xff0c;Allen Institute for AI 發布了 olmOCR&#xff0c;這是一個基于 Qwen2-VL-7B 視覺語言模型&#xff08;VLM&#xff09;的開源工具&#xff0c;用于處理 PDF 和其他復雜文檔的 OCR&#xff08;光學字符識別&#xff09;。開發團隊對該工具的…

移動端六大語言速記:第14部分 - 數據庫操作

移動端六大語言速記:第14部分 - 數據庫操作 本文將對比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift這六種移動端開發語言在數據庫操作方面的特性,幫助開發者理解和掌握各語言的數據庫編程能力。 14. 數據庫操作 14.1 SQL查詢 各語言SQL查詢實現方式對比: 特性Ja…

有哪些反爬機制可能會影響Python爬取視頻?如何應對這些機制?

文章目錄 前言常見反爬機制及影響1. IP 封禁2. 驗證碼3. 請求頭驗證4. 動態加載5. 加密與混淆6. 行為分析 應對方法1. 應對 IP 封禁2. 應對驗證碼3. 應對請求頭驗證4. 應對動態加載5. 應對加密與混淆6. 應對行為分析 前言 在使用 Python 爬取視頻時&#xff0c;會遇到多種反爬…

ESP32開發入門:基于VSCode+PlatformIO環境搭建指南

前言 ESP32作為一款功能強大的物聯網開發芯片&#xff0c;結合PlatformIO這一現代化嵌入式開發平臺&#xff0c;可以大幅提升開發效率。本文將詳細介紹如何在VSCode中搭建ESP32開發環境&#xff0c;并分享實用開發技巧。 一、環境安裝&#xff08;Windows/macOS/Linux&#xf…

DeepSeek:穿透行業知識壁壘的搜索引擎攻防戰

DeepSeek&#xff1a;穿透行業知識壁壘的搜索引擎攻防戰 文 / 產業智能觀察組&#xff08;人機協同創作&#xff09; 一、搜索引擎的"認知折疊"危機 2024年Q1數據顯示&#xff0c;百度搜索結果前10頁中&#xff0c;61.7%的內容存在"偽專業化"現象——看似…

SQL 外鍵(Foreign Key)詳細講解

1. 什么是外鍵&#xff1f;?? ??定義??&#xff1a;外鍵是數據庫表中的一列&#xff08;或一組列&#xff09;&#xff0c;用于??建立兩個表之間的關聯關系??。外鍵的值必須匹配另一個表的主鍵&#xff08;Primary Key&#xff09;或唯一約束&#xff08;Unique Con…

5G中的DU和CU的作用

在5G網絡架構中&#xff0c;CU&#xff08;Centralized Unit&#xff0c;集中單元&#xff09; 和 DU&#xff08;Distributed Unit&#xff0c;分布單元&#xff09; 是無線接入網&#xff08;RAN&#xff09;的重要組成部分&#xff0c;它們的分工和作用如下&#xff1a; 1.…

深度解析 n8n:強大的開源工作流自動化平臺

在數字化時代&#xff0c;企業和個人面臨著日益復雜的工作流程和多樣化的應用工具&#xff0c;如何高效整合這些資源、實現工作流的自動化成為提升效率的關鍵。n8n 作為一款開源的工作流自動化平臺&#xff0c;憑借其強大的功能、廣泛的應用集成能力和靈活的部署方式&#xff0…

ruby超高級語法

以下是 Ruby 中一些 極度硬核 的語法和底層特性&#xff0c;涉及元編程的深淵、虛擬機原理、語法黑魔法等&#xff0c;適用于追求極限的 Ruby 開發者&#xff1a; 高級語法一 一、語法核彈級操作 1. 動態修改繼承鏈 class A; def foo; "A"; end end class B; def …

flutter 獲取通話記錄和通訊錄

Dart SDK version is 3.7.01 dependencies:flutter:sdk: flutterpermission_handler: ^11.0.1 # 權限管理flutter_contacts: ^1.1.92call_log: ^5.0.5cupertino_icons: ^1.0.8dev_dependencies:flutter_test:sdk: flutterflutter_lints: ^5.0.0 2 contact_and_calls_page.da…

bash腳本手動清空mysql表數據

文章目錄 1、bash腳本手動清空mysql表數據 1、bash腳本手動清空mysql表數據 #!/bin/bash# 配置區域&#xff08;修改此處&#xff09; MYSQL_USER"root" MYSQL_PASSWORD"123456" MYSQL_HOST"localhost" DATABASES("hps-base:base_test_ite…

Spark Core編程

一文讀懂Spark Core編程核心要點 最近在學習大數據處理框架Spark&#xff0c;今天來給大家分享一下Spark Core編程中非常重要的內容&#xff0c;包括RDD算子、累加器和廣播變量&#xff0c;希望能幫助大家更好地理解和掌握Spark編程。先來說說RDD算子&#xff0c;它是Spark編程…

SDP(一)

SDP(Session Description Protocol)會話描述協議相關參數 Session Description Protocol Version (v): 0 --說明&#xff1a;SDP當前版本號 Owner/Creator, Session Id (o): - 20045 20045 IN IP4 192.168.0.0 --說明&#xff1a;發起者/創建者 會話ID&#xff0c;那么該I…

HarmonyOS:組件布局保存至相冊

一&#xff0c;需求背景 有這樣一個需求&#xff0c;將頁面上的某個自定義組件以圖片的形式保存至相冊。 二&#xff0c;需求拆解 根據需求分析&#xff0c;可將需求拆解成兩步&#xff1a; 1&#xff0c;將組件轉換成圖片資源&#xff1b; 2&#xff0c;將圖片保存到相冊…

算法中的數論基礎

算法中的數論基礎 本篇文章適用于算法考試或比賽之前的臨場復習記憶&#xff0c;沒有復雜公式推理&#xff0c;基本上是知識點以及函數模版&#xff0c;涵蓋取模操作、位運算的小技巧、組合數、概率期望、進制轉換、最大公約數、最小公倍數、唯一分解定理、素數、快速冪等知識…

Redis下載穩定版本5.0.4

https://www.redis.net.cn/download/ Redis下載 Redis 版本號采用標準慣例:主版本號.副版本號.補丁級別,一個副版本號就標記為一個標準發行版本,例如 1.2,2.0,2.2,2.4,2.6,2.8,奇數的副版本號用來表示非標準版本,例如2.9.x發行版本是Redis 3.0標準版本的非標準發行版本…

?UniApp 安卓打包完整步驟(小白向)

? ?一、環境準備? ?安裝 HBuilderX? 下載最新版 HBuilderX 并安裝&#xff08;官方 IDE&#xff0c;支持一鍵打包&#xff09;?16確保已安裝 Node.js&#xff08;用于依賴管理&#xff09;?26 ?配置 Android 開發環境? 安裝 ?Java JDK 17?&#xff08;建議選擇穩定…

【Springboot知識】Springboot配置加載機制深入解讀

文章目錄 配置加載概述**Spring Boot 配置加載機制詳解****一、配置加載順序&#xff08;優先級由低到高&#xff09;****二、關鍵配置機制說明****1. Profile 機制****2. 外部化配置****3. 配置屬性綁定到 Bean****4. 動態覆蓋配置** **三、配置加載流程圖****2. 配置導入&…

AI圖像生成

要通過代碼實現AI圖像生成&#xff0c;可以使用深度學習框架如TensorFlow、PyTorch或GANs等技術。下面是一個簡單的示例代碼&#xff0c;演示如何使用GANs生成手寫數字圖像&#xff1a; import torch import torchvision import torchvision.transforms as transforms import …

基于springboot的個人博客系統

一、系統架構 前端&#xff1a;html | bootstrap | jquery | css | ajax 后端&#xff1a;springboot | mybatis 環境&#xff1a;jdk1.8 | mysql | maven 二、代碼及數據 三、功能介紹 01. 注冊 02. 登錄 03. 管理后臺-首頁 04. 管理后臺-文章-所有文…