基礎算法篇(4)(藍橋杯常考點)—數據結構(進階)

前言

這期將會講到基礎算法篇里面的數據結構(進階),主要包括單調棧,單調隊列,并查集,擴展域并查集,帶權并查集,字符串哈希,Trie樹。

數據結構(進階)正文

單調棧

里面存儲的單增或者單減的棧

應用:

1.尋找當前元素左側,離它最近,并且比它大的元素在哪

2.尋找當前元素左側,離它最近,并且比它小的元素在哪

3.尋找當前元素右側,離它最近,并且比它大的元素在哪

4.尋找當前元素右側,離它最近,并且比它小的元素在哪

尋找當前元素左側,離它最近,并且比它大的元素在哪
int a[N]里面存數(已存好)
ret里面存的答案
stack<int>st;//維護一個單調遞減的棧,里面存的是下標
for(int i = 1;i<=n;i++)
{
//棧里面小于等于a[i]的元素全部出棧while(st.size()&&a[st.top()]<=a[i]) st.pop();
//此時棧頂元素存在,棧頂元素就是所求結果if(st.size()) ret[i]=st.top();
st.push(i);}
尋找當前元素右側,離它最近,并且比它大的元素在哪
改成for(int i = n;i>=1;i--)
尋找當前元素左側,離它最近,并且比它小的元素在哪
int a[N]里面存數(已存好)
ret里面存的答案
stack<int>st;//維護一個單調遞增的棧,里面存的是下標
for(i=1;i<=n;i++)
{
//棧里面大于等于a[i]的元素全部出棧
while(st.size()&&a[st.top()]>=a[i])st.pop();//這里的符號是跟上面的唯一區別
//此時棧頂元素存在,棧頂元素就是所求結果
if(st.size()) ret[i]=st.top();
st.push(i);}
尋找當前元素右側,離它最近,并且比它小的元素在哪
把上面改為for(int i=n;i>=1;i--)即可//n次逆遍歷可以記一下是這個
總結:
找左側,正遍歷;找右側,逆遍歷;
比它大,單調減;比它小,單調增。//構造___棧
例題: 洛谷  P1901 發射站

洛谷 P1901 發射站

單調隊列

是一個存單調元素的雙端隊列

應用:解決滑動窗口內的最大值最小值問題

(前面基礎算法的滑動窗口不是用來求其中的最值的)

洛谷 P1886 滑動窗? /【模板】單調隊列

例題:洛谷  P1886 滑動窗? /【模板】單調隊列
int a[N]里面存的元素(已存好)
窗口內最大值:
從左往右遍歷元素,維護一個單調遞減的雙端隊列
當前元素進隊之后,注意維護隊列內的元素在大小為k的窗口內
此時隊頭元素就是最大值
代碼:
deque<int>q;//存下標
for(int i = 1;i<=n;i++)
{while(q.size()&&a[q.back()]<=a[i])q.pop_back();
q.push_back(i);
if(q.back()-q.front()+1>k) q.pop_front();
if(i>=k)cout<<a[q.front()]<<" ";}窗口內最小值:
從左往右遍歷元素,維護一個單調遞增的雙端隊列
當前元素進隊之后,注意維護隊列的元素在大小為k的窗口內
此時隊頭元素就是最小值

并查集

并查集是一種用于維護元素所屬集合的數據結構,用雙親表示法來實現

應用eg:維護連通塊的信息

相關的一些概念:

查詢操作:查找元素x屬于哪一個集合,一般會在每個集合中選取一個元素作為代碼,查詢的是這個集合中的代表元素

合并操作:將元素x所在的集合與元素y所在的集合合并成一個元素

(注意:合并的是元素所屬的集合,而并非單單兩個元素)

判斷操作:判斷元素x和y是否在同一個集合

洛谷 P1551 親戚

并查集的實現:
例題:洛谷  P1551 親戚
1.初始化:讓元素自己指向自己即可
int fa[N];一般并查集用fa來表示
for(int i=1;i<=n;i++) fa[i] = i;2.查詢操作:就是一直向上"找爸爸"(這個find可以多次使用)
int find(int x)//查詢x所在集合的代表元素是誰
return fa[x] == x?x:find(fa[x]);//是x就返回x,不是就find(fa[x])3.合并操作:(重復合并不會出錯)
讓元素x所在集合的代表元素指向元素y所在集合的代表元素
void un(int x,int y)
{ int fx = find(x);int fy = find(y);fa[fx] = fy;}4.判斷操作
看看兩者所在集合的總代表元素是否相同
bool issame(int x,int y)
{return find(x) == find(y);}

擴展域并查集

元素之間存在多種關系比如:朋友和敵人 而不像上面只存在:親戚這樣一種關系的話,就要用擴展域并查集

和普通并查集的區別:將每個元素拆分成多個域,每個域代表?種狀態或者關系

洛谷 P1892 [BOI2003] 團伙

例題:洛谷  P1892 [BOI2003] 團伙
這里只寫不同點:
find和un與上面的寫法一模一樣
//兩種關系,所以N*2:x的母敵人是x+n
int fa[N*2];
//初始化:
for(int i=1;i<=n*2;i++) fa[i]=i;
while(m--)//m是題目中的"m個關系"
{if(op == 'F')  un(x,y);else//敵人,讀取的是y和x是敵人關系{//存法:這倆都得寫,少一個都不行un(x,y+n);//這兩是朋友關系un(y,x+n);//這兩是朋友關系}
}

帶權并查集

概念:就是在普通并查集的基礎上,為每個結點增加一個權值。這個權值可以表示當前結點與父結點之間的信息(因為find那我們用的路徑壓縮,因為最終這個權值是當前結點相對于根節點的信息)

洛谷 P1196 [NOI2002] 銀河英雄傳說

帶權并查集的一些操作:(這里的d[N]以到父結點的距離為例)
例題:洛谷  P1196 [NOI2002] 銀河英雄傳說
新加了一個d[N]1.初始化:
多初始化個d[i]即可2.查詢操作:(對這種代碼來說,一個結點只能進行一次這種find操作!)
int find(int x)
{ if(fa[x]==x) return x;int t = find(fa[x]);//這一步要先搞d[x]+=d[fa[x]];//不為距離時可能會變為其他
return fa[x] = t;//完成路徑壓縮
}3.合并操作://x所在集合與y所在集合合并,x與y之間的權值是w
void un (int x,int y, int w)
{int fx = find(x),fy = find(y);
if(fx!=fy){fa[fx] = fy;d[fx]= d[y]+w-d[x]; //可能會變,這里是拿距離舉例的} }4.查詢操作://查詢y與x之間的距離
int query(int x,int y)
{int fx = find(x),fy = find(y);
//如果不在同一個集合中,說明距離未知(具體返回什么要看題意)if(fx!=fy)return 0x3f3f3f3f;
return d[y]-d[x];
}

字符串哈希

一般利用前綴和思想去預處理字符串匯總每個前綴的哈希值

(使用前提:需要多次詢問一個字符串的子串的哈希值)

核心思想:把字符串映射成P進制數字

P一般選擇13331或者131

字符串哈希的作用:

字符串哈希一般用于判斷兩個字符串及其各子串是否相等

(和字典樹的區別是這個字符串哈希側重于判斷功能)

洛谷 P10468 兔?與兔?

例題:洛谷  P10468 兔?與兔?
前綴字符串哈希模板:
typedef unsigned lon long ULL;
P = 13331;
int len;
string s;//一般都要搞一下s = ' '+s;來讓i從1開始搞
ULL f[N];//前綴哈希數組
ULL p[N];//記錄P的i次方->p[i]為P的i次方
//處理前綴哈希數組以及P的i次方數組
void init_hash()
{f[0] = 0;p[0] = 1;for(int i = 1;i<=len;i++){ f[i]=f[i-1]*P+s[i];p[i]=p[i-1]*P;} }
//快速求得任意區間的哈希值
ULL get_hash(int l,int r)
{return f[r]-f[l-1]*p[r-l+1];}如果題目只是簡單的求單個字符串的哈希值:
ULL gethash()
{ULL ret = 0;for(int i =1;i<=len;i++){ret = ret*p+s[i];} return ret;}

Trie樹(又叫字典樹或前綴樹)

是一種能夠快速插入和查詢字符串的數據結構

理解:我們可以把字典樹想象成一顆多叉樹,每一條邊代表一個字符,從根節點到某個節點的路徑就代表了一個字符串

作用:

1.查詢某個單詞是否出現過,并且出現幾次

2.查詢有多少個單詞是以某個字符串為前綴

3.查詢所有以某個前綴開頭的單詞

字典樹的實現:
默認需要存的全是小寫字母1.準備工作int tree[N][26],p[N],e[N];//N一般令為所有字符串中一共有多少個字符
// p[i]表示第i個被開辟的點被經過了多少次,
//e[i]表示以第i個被開辟的點為結尾的有多少個
int idx;2.插入字符串
void insert(string&s)
{int cur = 0;//從根節點開始p[cur]++;//這個格子經過一次for(auto ch:s){
//這個path的表達式常改!!!依據題意改int path = ch - 'a';//如果沒有路if(tree[cur][path] == 0) tree[cur][path]= ++idx;cur = tree[cur][path];p[cur]++ }e[cur]++;
}3.查詢字符串出現的次數:
int find(string&s)
{int cur = 0;for(auto ch:s){int path = ch - 'a';if(tree[cur][path] == 0) return 0;cur = tree[cur][path];} return e[cur];}4.查詢有多少個單詞以字符串s為前綴:int find_pre(string&s)
{int cur = 0;for(auto ch:s){int path = ch-'a';if(tree[cur][path] == 0) return 0;cur = tree[cur][path];} return p[cur];}例題:洛谷  P2580 于是他錯誤的點名開始了

洛谷 P2580 于是他錯誤的點名開始了

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

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

相關文章

【AI學習】初步了解Gradio

Gradio 是一個開源的 Python 庫&#xff0c;專注于快速構建交互式 Web 界面&#xff0c;特別適用于機器學習模型、數據科學項目或任意 Python 函數的演示與部署。它通過極簡的代碼實現前后端一體化&#xff0c;無需前端開發經驗即可創建功能豐富的應用。以下是 Gradio 的核心特…

Overleaf 論文提交 Arxiv

Contents References 清除 Overleaf 中所有編譯 error&#xff0c;并且保證 main.tex 文件在 project 最上層參考文件 .bib 轉 .bbl. project 編譯成功后可以在 Overleaf 的 Recompile 按鈕右側找到 “Logs and output files”&#xff0c;點進去之后右下角可以點開 “Other lo…

【Android Audio】Parameter Framework - pfw

Parameter Framework - Android AudioPolicy Engine 使用 libengineconfigurable.so 來取締默認安卓音頻引擎 libenginedefault.so&#xff0c;因為默認安卓音頻引擎是通過代碼來決定策略&#xff0c;然而 libengineconfigurable 采用讀取pfw類型的文件來實現音頻策略配置。 …

服務器虛擬化技術深度解析:醫藥流通行業IT架構優化指南

一、服務器虛擬化的定義與原理 &#xff08;一&#xff09;技術定義&#xff1a;從物理到虛擬的資源重構 服務器虛擬化是通過軟件層&#xff08;Hypervisor&#xff09;將物理服務器的CPU、內存、存儲、網絡等硬件資源抽象為邏輯資源池&#xff0c;分割成多個相互隔離的虛擬機…

babel-runtime 如何縮小打包體積

&#x1f916; 作者簡介&#xff1a;水煮白菜王&#xff0c;一位前端勸退師 &#x1f47b; &#x1f440; 文章專欄&#xff1a; 前端專欄 &#xff0c;記錄一下平時在博客寫作中&#xff0c;總結出的一些開發技巧和知識歸納總結?。 感謝支持&#x1f495;&#x1f495;&#…

劍指Offer(數據結構與算法面試題精講)C++版——day7

劍指Offer&#xff08;數據結構與算法面試題精講&#xff09;C版——day7 題目一&#xff1a;最多刪除一個字符得到回文題目二&#xff1a;回文子字符串的個數題目三&#xff1a;刪除倒數第k個節點 題目一&#xff1a;最多刪除一個字符得到回文 這里我們可以在經典的字符串回文…

2025年常見滲透測試面試題(題目+回答)

網絡安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 常見面試題 一、滲透測試經歷與技術復盤 二、高頻漏洞類型與攻防體系 三、滲透工具鏈與技術特性 四、…

大數據與人工智能之大數據架構(Hadoop、Spark、Flink)

一、核心特性與架構設計 1. Hadoop&#xff1a;分布式批處理的基石 核心組件&#xff1a; HDFS&#xff1a;分布式文件系統&#xff0c;支持大規模數據存儲。MapReduce&#xff1a;基于“分而治之”的批處理模型&#xff0c;適合離線分析。 架構特點&#xff1a; 批處理主導&…

從IoT到AIoT:智能邊界的拓展與AI未來趨勢預測

文章目錄 引言&#xff1a;從連接萬物到感知萬物1. AIoT的本質&#xff1a;將智能嵌入萬物2. AIoT的推動力量與挑戰2.1 推動力量2.2 關鍵挑戰 3. 五大AIoT未來趨勢預測趨勢一&#xff1a;邊緣智能將成為主流架構趨勢二&#xff1a;AI模型將向自適應與多任務演進趨勢三&#xff…

從本地新建文件夾到拉取遠程倉庫 dev 分支的完整步驟

《從本地新建文件夾到拉取遠程倉庫 dev 分支的完整步驟》 下面為你詳細介紹從本地新建文件夾開始&#xff0c;將遠程倉庫的 dev 分支拉取到本地的具體步驟&#xff1a; 1. 創建新文件夾 在本地電腦上新建一個文件夾&#xff0c;作為存放項目代碼的目錄。你可以通過圖形界面操…

python/pytorch雜聊

Dataset 是否需要自己定義&#xff1a;如果你使用的數據集不是 PyTorch 提供的標準數據集&#xff08;如 MNIST、CIFAR-10 等&#xff09;&#xff0c;那么你需要繼承 torch.utils.data.Dataset 類并實現兩個方法&#xff1a;__len__() 和 __getitem__()。__len__() 應該返回數…

PHP 安全 E-mail

PHP 安全 E-mail 引言 隨著互聯網的普及和電子商務的發展,電子郵件成為了人們日常生活中不可或缺的通信工具。PHP作為一種廣泛使用的服務器端腳本語言,也經常被用于發送和接收電子郵件。然而,在PHP中處理電子郵件時,安全性問題不容忽視。本文將深入探討PHP安全發送電子郵…

【夜話系列】DelayQueue延遲隊列(下):實戰應用與面試精講

?? 本文是DelayQueue系列的下篇,聚焦實戰應用場景和性能優化。通過多個真實案例,帶你掌握DelayQueue在項目中的最佳實踐和性能調優技巧。 ?? 系列專欄推薦: JAVA集合專欄 【夜話集】JVM知識專欄數據庫sql理論與實戰小游戲開發文章目錄 一、DelayQueue實戰應用1.1 訂單超…

Redis(筆記)

簡介&#xff1a; 常用數據類型: 常用操作命令&#xff1a; Redis的Java客戶端&#xff1a; 操作字符串類型的數據&#xff1a; 操作Hash類型的數據&#xff1a; 操作列表類型的數據&#xff1a; 操作集合類型的數據&#xff1a; 操作有序集合類型數據&#xff1a; 通用命令…

PhotoShop學習05

1.選區基礎知識 選區&#xff0c;就是選定一些區域&#xff0c;我們對圖片的更改只在選區內生效&#xff0c;這樣可以精細調整圖片的部分而不會影響整體。它的快捷鍵是M。 我們用點擊鼠標后滑動就會出現虛線框&#xff0c;虛線框內的就是我們選定的區域。這時我們再滑動就會創…

使用Redission實現分布式鎖

分布式鎖在分布式系統中非常重要&#xff0c;主要用于解決多個進程/服務并發訪問共享資源時的數據一致性問題。在日常開發中常用于&#xff1a; 1. 防止重復操作&#xff08;冪等性控制&#xff09; 場景&#xff1a;用戶重復提交訂單、重復支付、重復點擊等。 示例&#xff1…

VScode 畫時序圖(FPGA)

1、先安裝插件&#xff1a; 2、然后就可以編寫一個.js文件&#xff0c;如下&#xff1a; {signal: [{name: clk, wave: p.......|..},{name: rstn, wave: 01......|..},{name: din_vld, wave: 0.1.0...|..},{name: din, wave: "x.x...|..", data: ["D0", …

嵌入式學習筆記——I2C

IIC協議詳解 一、IIC協議簡介二、IIC總線結構圖三、IIC通信流程詳解1. 空閑狀態 : 雙高空閑2. 起始信號&#xff08;START&#xff09;: 時高數下開始3. 停止信號&#xff08;STOP&#xff09;: 時高數上結束4. 數據傳輸格式 : 時高數穩&#xff0c;時低數變5. 應答信號 四、寫…

Apifox Helper 與 Swagger3 區別

核心定位差異 Apifox Helper 定位&#xff1a;基于 IDEA 的代碼注釋解析工具&#xff0c;與 Apifox 平臺深度集成&#xff0c;實現文檔自動生成接口管理測試協作的一體化流程。 特點&#xff1a; 通過解析 Javadoc、KDoc 等注釋生成文檔&#xff0c;代碼零侵入&#xff08;無…

單片機實現多線程的方法匯總

在單片機上實現“多線程”的方法有幾種&#xff0c;下面按照從簡單到復雜、從輕量到系統性來列出常見的方案&#xff1a; &#x1f9f5; 一、偽多線程&#xff08;最輕量&#xff09; 方法&#xff1a;主循環 狀態機 / 定時器輪詢 主循環中輪流調用各個任務的處理函數&#x…