【優先算法】思還故里閭,欲歸道無因 - 前綴和

在這里插入圖片描述

本篇博客給大家帶來的是前綴和算法的知識點, 也是一樣通過OJ題理解,掌握,應用該算法.
🐎文章專欄: 算法
🚀若有問題 評論區見
? 歡迎大家點贊 評論 收藏 分享
如果你不知道分享給誰,那就分享給薯條.
你們的支持是我不斷創作的動力 .

王子,公主請閱🚀

  • 要開心
    • 要快樂
      • 順便進步
    • 1. 和為K的子數組
    • 2. 和可被 K 整除的?數組(藍橋杯真題)
    • 3. 連續數組
    • 4. 矩陣區域和

要開心

要快樂

順便進步

1. 和為K的子數組

題目鏈接: 560. 和為 K 的子數組

題目描述:

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

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

示例 1:

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

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

解法一: 暴力解法

在這里插入圖片描述

定義計數變量count, 兩層循環遍歷數組, 每次 j 從 i 的位置開始,
找到滿足 [ i , j ] 區間元素和等于k時,count++. 時間復雜度為O(N^2)

解法二: 前綴和 + 哈希表

1. 問題轉換并分析

在這里插入圖片描述

①是 以 i 位置為結尾的子數組,且①滿足數組元素為 k.
由此圖便可將問題轉化為: 當遍歷數組到 i 位置時, [ 0 , i-1 ]區間中前綴和為sum[i] - k的個數.

這個時候不要直接去求前綴和數組, 然后遍歷找滿足條件的前綴和. 如果這么做那時間復雜度還是O(N^2)并且空間復雜度還是O(N), 并不見得比暴力解法要好.
要找前綴和并且其滿足sum[i] - k, 可以利用哈希表來找, 哈希表本身就是用來查找的. 哈希表: <前綴和,出現次數>

2. 算法思路

在這里插入圖片描述

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

3. 處理細節

1. 我們不用真的初始化一個前綴和數組,因為我們只關心在 i 位置之前,有多少個前綴和等于sum[i] - k 。因此,我們僅需用一個哈希表,一邊求當前位置的前綴和,一邊存下之前每?種前綴和出現的次數。 不要把前綴和都求出來后再加入哈希表, 原本應該是[ 0 , i-1 ] 的前綴和,但求完一并加入 會 使 [ i , n-1] 的前綴和也加進來, 假設[ i , n-1 ] 也有滿足條件的前綴和, 就會多算.

2. 如果整個數組和為 k , 那么此時并不存在一個區間讓我去找 前綴和 = sum[i] - k, 但是sum[i] = k 這個情況確實存在, 所以在我開始遍歷數組之前, 應該先map.put(0,1), sum[i] - k = 0時, 次數賦為1.

在這里插入圖片描述

4. 代碼實現

class Solution {public int subarraySum(int[] nums, int k) {Map<Integer,Integer> map = new HashMap<>();//將前綴和為0的初始次數設置為1, 因為 k 有可能等于nums數組中某個元素的值.map.put(0,1);int sum = 0,ret = 0;for(int x : nums) {sum += x;//計算當前位置的前綴和.ret += map.getOrDefault(sum-k,0);//統計結果.map.put(sum,map.getOrDefault(sum,0)+1);//將當前位置的前綴和sum加入哈希表.}return ret;}
}

2. 和可被 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

解法一: 暴力枚舉

做法與上題基本一致, 就是枚舉出所有子數組的和, 時間復雜度為O(N^2).

解法二: 前綴和 + 哈希表

第一點 必要前置知識:

1. 同余定理
如果(a - b) % p = 0 , 那么 a % p = b % p . 即 如果兩個數相減的差能被 p 整除,那么這兩個數對 p 取模的結果相同. 例如: (7 - 4) % 3 = 0, 7 % 3 = 1, 4 % 3 = 1;

在這里插入圖片描述根據同余定理就可以把問題轉換成, 在[0 , i-1]區間中找到滿足 前綴和 % k 等于 sum[i] % k 的 所有前綴和. (這也是本題的核心.)

2. 負數取模

C++和Java中, 負數 % 正數 結果為 負數, 為了防止 重復算,統一將結果化為正數. 比如 -1 % 3 = -1 換成 (-1 % 3 + 3) % 3 = 2 . 即 a % p -> (a % p + p) % p .

第二: 具體步驟(與上題無異, 不同的是,此題中map第一個位置放的時前綴和 % k 的值. 并且確保是正數.)
在這里插入圖片描述

設 i 為數組中的任意位置,? sum[i] 表示 [0, i] 區間內所有元素的和。
? 想知道有多少個「以 i 為結尾的可被 k 整除的子數組」,就要找到有多少個起始位置為 x1, x2, x3… 使得 [x, i] 區間內的所有元素的和可被 k 整除。
? 設 [0, x ] (x < i)區間內所有元素之和等于 a , [0, i] 區間內所有元素的和等于 b ,可得
(b - a) % k == 0 。
? 由同余定理可得, [0, x ] 區間與 [0, i] 區間內的前綴和同余。于是問題就變成:
? 找到在 [0, i - 1] 區間內,有多少前綴和的余數等于 sum[i] % k 的即可。
我們不用真的初始化?個前綴和數組,因為我們只關心在 i 位置之前,有多少個前綴和等于sum[i] - k 。因此,我們僅需用一個哈希表,一邊求當前位置的前綴和,一邊存下之前每?種前綴和出現的次數。

第三 代碼實現

class Solution {public int subarraysDivByK(int[] nums, int k) {Map<Integer,Integer> map = new HashMap<Integer,Integer>();map.put(0,1);//還是一樣的,[0,i] 當sum = k時,不存在區間,但sum[i] = k存在.int sum = 0,ret = 0;for(int x : nums) {sum += x;//當前位置的前綴和int tmp = (sum % k + k) % k;//前綴和模k 的余數,原本是sum % k, 但是Java和C++存在負數模正數等于負數的問題,一并化成正數.ret += map.getOrDefault(tmp,0);map.put(tmp,map.getOrDefault(tmp,0)+1);}return ret;}
}

3. 連續數組

題目鏈接: 525. 連續數組

題目描述:

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

示例 1:

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

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

1. 暴力枚舉

枚舉出所有子數組, 檢查子數組是否滿足要求,時間復雜度為O(N^2).

2. 前綴和 + 哈希表

第一 問題分析與轉換
原數組中的元素只有0和1, 題目要求的是 0 和 1 個數相等的最長子數組, 將所有的 0 換成 -1, 問題就轉換成 求 和為0的最長子數組的長度.

在這里插入圖片描述

第二 處理細節

1. 哈希表<In,In>的兩個位置分別存放 [ 0 , i ]前綴和 與 位置 i .

在這里插入圖片描述

2. 當區間[ 0 , i ]的sum[i] = 0時, 0 < j < i,不存在[0 , j] 區間. 默認一個前綴和為0的情況, 只能以 -1 為結束位置.

3. 如果有重復的sum[ i ] , 保留前面先算出來的 <sum ,i>, 舍棄后面的, 因為先算出來的更靠左邊, 離 i 的距離更大, 本題要求的就是最大長度.

在這里插入圖片描述

第三 步驟

在這里插入圖片描述

設 i 為數組中的任意位置,? sum[i] 表? [0, i] 區間內所有元素的和。
想知道最?的「以 i 為結尾的和為 0 的?數組」,就要找到從左往右第?個 x1 使得
[x1, i]區間內的所有元素的和為 0 。那么 [0, x1 - 1] 區間內的和是不是就是 sum[i] 了。于是問題
就變成:
? 找到在 [0, i - 1] 區間內,第?次出現 sum[i] 的位置即可。
我們不?真的初始化?個前綴和數組,因為我們只關?在 i 位置之前,第?個前綴和等于 sum[i]的位置。因此,我們僅需??個哈希表,?邊求當前位置的前綴和,?邊記錄第?次出現該前綴和的
位置。

第四 代碼實現

class Solution {public int findMaxLength(int[] nums) {Map<Integer,Integer> hash = new HashMap<>();hash.put(0,-1); //當[0,i]sum = 0時,默認存在一個前綴和為0的情況.并且以-1為結束位置.int sum = 0,ret = 0;for(int i = 0;i < nums.length;++i) {if(nums[i] == 0) {sum += -1; //將數組中所有的 0 替換成 -1.}else {sum += nums[i];//求出當前位置的前綴和}if(hash.containsKey(sum-0)) {ret = Math.max(ret,i - hash.get(sum));}else{//有重復的只保留前面的那一對<sum,i>.  hash.put(sum,i);}}return ret;}
}

4. 矩陣區域和

題目鏈接: 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

本篇博客到這里就結束啦, 感謝觀看 ???

🐎期待與你的下一次相遇😊😊😊

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

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

相關文章

億道三防丨三防筆記本是什么意思?和普通筆記本的優勢在哪里?

三防筆記本是什么意思&#xff1f;和普通筆記本的優勢在哪里&#xff1f; 在現代社會中&#xff0c;筆記本電腦已經成為人們工作和生活中不可或缺的一部分。然而&#xff0c;在一些特殊行業或環境中&#xff0c;普通筆記本電腦由于其脆弱性和對環境條件的敏感性&#xff0c;往…

SOME/IP 協議詳解——服務發現

文章目錄 1. Introduction &#xff08;引言&#xff09;2. SOME/IP Service Discovery (SOME/IP-SD)2.1 General&#xff08;概述)2.2 SOME/IP-SD Message Format2.2.1 通用要求2.2.2 SOME/IP-SD Header2.2.3 Entry Format2.2.4 Options Format2.2.4.1 配置選項&#xff08;Co…

MATLAB語言的函數實現

MATLAB語言中的函數實現詳解 引言 MATLAB&#xff08;矩陣實驗室&#xff09;是一種高級語言和互動環境&#xff0c;廣泛應用于數值計算、數據分析、可視化以及工程與科學計算等多個領域。MATLAB的強大之處在于其豐富的函數庫以及用戶自定義函數的能力。本文將深入探討MATLAB…

Go語言之路————go環境的初始化

Go語言之路————go環境的初始化 前言一、Go的安裝二、環境配置三、初始化一個新項目四、常用的一些指令 前言 我是一名多年Java開發人員&#xff0c;因為工作需要現在要學習go語言&#xff0c;Go語言之路是一個系列&#xff0c;記錄著我從0開始接觸Go&#xff0c;到后面能正…

鼠標過濾驅動

文章目錄 概述代碼參考資料 概述 其編寫過程大體與鍵盤過濾驅動相似&#xff0c;只需要切換一下附加的目標設備以及創建的設備類型等。但在該操作后依然無法捕獲到Vmware創建的win7操作系統的鼠標irp信息&#xff0c;于是通過在獲取鼠標驅動&#xff0c;遍歷其所有的設備進而附…

鴻蒙UI開發——基于onTouch事件實現表情選擇膠囊

1、背 景 有朋友留言說&#xff0c;抖音APP中&#xff0c;長按評論按鈕觸發的快捷表情選擇膠囊動畫比較好&#xff08;效果如下圖&#xff09;&#xff0c;希望使用鴻蒙ArkTs也實現一個類似的。 本文在鴻蒙ArkTs下也實現一個類似的效果&#xff0c;如下&#xff1a; 首先&…

Node.js——http 模塊(二)

個人簡介 &#x1f440;個人主頁&#xff1a; 前端雜貨鋪 &#x1f64b;?♂?學習方向&#xff1a; 主攻前端方向&#xff0c;正逐漸往全干發展 &#x1f4c3;個人狀態&#xff1a; 研發工程師&#xff0c;現效力于中國工業軟件事業 &#x1f680;人生格言&#xff1a; 積跬步…

研華 PCI-1751 驅動更新導LabVIEW致程序異常

問題描述&#xff1a; 某 LabVIEW 程序長期運行正常&#xff0c;但在使用研華 PCI-1751 數據采集卡運行一段時間后&#xff0c;程序開始出現不正常的行為。具體過程如下&#xff1a; 初始問題&#xff1a; 更換新的 PCI-1751 板卡后&#xff0c;驅動程序被更新&#xff0c;但程…

接上篇基于Alertmanager 配置釘釘告警

Alertmanager 是一個用于處理和管理 Prometheus 警報的開源工具。它負責接收來自 Prometheus 服務器的警報&#xff0c;進行去重、分組、靜默、抑制等操作&#xff0c;并通過電子郵件、PagerDuty、Slack 等多種渠道發送通知。 主要功能 去重&#xff1a;合并相同或相似的警報&…

網絡原理(三)—— 傳輸層 之 UDP 和 TCP協議

傳輸層 在傳輸層兩大關鍵的協議就是UDP和TCP協議了&#xff0c;除此之外&#xff0c;還有別的傳輸層協議&#xff0c;本文章將介紹UDP和TCP協議&#xff0c;重點介紹TCP協議。 首先回顧TCP和UDP 的特點&#xff1a; UDP&#xff1a;不可靠傳輸&#xff0c;面向數據包&#xf…

針對服務器磁盤爆滿,MySql數據庫始終無法啟動,怎么解決

&#xff08;點擊即可進入聊天助手&#xff09; 很多站長在運營網站的過程當中都會遇到一個問題,就是網站突然無法打開,數據一直無法啟動 無論是強制重啟還是,刪除網站內的所有應用,數據庫一直無法啟動 這個時候,就需要常見的運維手段了,需要對服務器后臺各個資源,進行逐一排查…

高性能現代PHP全棧框架 Spiral

概述 Spiral Framework 誕生于現實世界的軟件開發項目是一個現代 PHP 框架&#xff0c;旨在為更快、更清潔、更卓越的軟件開發提供動力。 特性 高性能 由于其設計以及復雜精密的應用服務器&#xff0c;Spiral Framework框架在不影響代碼質量以及與常用庫的兼容性的情況下&a…

【面試題】Spring/SpringBoot部分[2025/1/6 ~ 2025/1/12]

Spring/SpringBoot部分[2025/1/6 ~ 2025/1/12] 1. 說說 Spring 啟動過程&#xff1f;2. 說說 Springboot 的啟動流程&#xff1f;3. 你了解的 Spring 都用到哪些設計模式&#xff1f;4. Spring 有哪幾種事務傳播行為?5. SpringBoot 是如何實現自動配置的&#xff1f;6. Spring…

【機器學習:十八、更高級的神經網絡概念】

1. 梯度下降法的改進&#xff1a;Adam算法 1.1 Adam算法簡介 Adam&#xff08;Adaptive Moment Estimation&#xff09;是一種優化算法&#xff0c;結合了動量梯度下降和 RMSProp 的優點&#xff0c;在處理稀疏梯度和高維空間優化時表現尤為出色。其核心在于動態調整每個參數…

計算機網絡之---VPN與隧道協議

VPN與隧道協議 VPN&#xff08;虛擬專用網絡&#xff09;和隧道協議是現代網絡安全技術的重要組成部分&#xff0c;它們主要用于在不安全的公共網絡&#xff08;如互聯網&#xff09;上建立一個安全的私密網絡連接。VPN通過加密通信和認證機制&#xff0c;確保數據的隱私性和完…

【STM32-學習筆記-6-】DMA

文章目錄 DMAⅠ、DMA框圖Ⅱ、DMA基本結構Ⅲ、不同外設的DMA請求Ⅳ、DMA函數Ⅴ、DMA_InitTypeDef結構體參數①、DMA_PeripheralBaseAddr②、DMA_PeripheralDataSize③、DMA_PeripheralInc④、DMA_MemoryBaseAddr⑤、DMA_MemoryDataSize⑥、DMA_MemoryInc⑦、DMA_DIR⑧、DMA_Buff…

SQL Server中可以通過擴展事件來自動抓取阻塞

在SQL Server中可以通過擴展事件來自動抓取阻塞&#xff0c;以下是詳細流程&#xff1a; 開啟阻塞跟蹤配置&#xff1a; ? 執行以下SQL語句來啟用相關配置&#xff1a; EXEC sp_configureshow advanced options, 1; RECONFIGURE; EXEC sp_configure blocked process thresh…

DNS解析域名簡記

域名通常是由: 權威域名.頂級域名.根域名組成的。 從左往右&#xff0c;級別依次升高&#xff0c;這和外國人從小范圍到大范圍的說話習慣相關。&#xff08;我們自己是更習慣先說大范圍再說小范圍&#xff0c;如XX省XX市XX區XX路&#xff09; DNS解析域名時&#xff0c;會先查…

【爬蟲】單個網站鏈接爬取文獻數據:標題、摘要、作者等信息

源碼鏈接&#xff1a; https://github.com/Niceeggplant/Single—Site-Crawler.git 一、項目概述 從指定網頁中提取文章關鍵信息的工具。通過輸入文章的 URL&#xff0c;程序將自動抓取網頁內容 二、技術選型與原理 requests 庫&#xff1a;這是 Python 中用于發送 HTTP 請求…

關于掃描模型 拓撲 和 傳遞貼圖工作流筆記

關于MAYA拓撲和傳遞貼圖的操作筆記 一、拓撲低模: 1、拓撲工作區位置: 1、準備出 目標 高模。 (高模的狀態如上 ↑ )。 2、打開頂點吸附,和建模工具區,選擇四邊形繪制. 2、拓撲快捷鍵使…