【算法專題訓練】19、哈希表

1、哈希表基礎知識

  • 以鍵值對的方式進行數據存儲
  • 優點:哈希表數據結構在插入、刪除或查找一個元素時,都只需要O(1)的時間

哈希表設計三要點:

  • 為了快速確定一個元素在哈希表中的位置,可以使用一個數組,元素的位置為他的哈希值除于數組長度的余數。
  • 由于多個哈希值不同的元素可能會被存入同一數組位置,數組的每個位置對應一個鏈表,因此存入同一位置的多個元素都被添加到同一個鏈表中。
  • 為了確保鏈表不會太長,就需要計算哈希表中元素的數目與數組長度的比值。當這個比值超過某個閾值時,就對數組進行擴容處理,并把哈希表中的所有元素重新分配位置。

2、LCR 030. O(1) 時間插入、刪除和獲取隨機元素

題目信息:

  • https://leetcode.cn/problems/FortPu/description/
設計一個支持在平均 時間復雜度 O(1) 下,執行以下操作的數據結構:insert(val):當元素 val 不存在時返回 true ,并向集合中插入該項,否則返回 falseremove(val):當元素 val 存在時返回 true ,并從集合中移除該項,否則返回 false 。
getRandom:隨機返回現有集合中的一項。每個元素應該有 相同的概率 被返回。示例 1:
輸入: inputs = ["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
[[], [1], [2], [2], [], [1], [2], []]
輸出: [null, true, false, true, 2, true, false, 2]
解釋:
RandomizedSet randomSet = new RandomizedSet();  // 初始化一個空的集合
randomSet.insert(1); // 向集合中插入 1 , 返回 true 表示 1 被成功地插入
randomSet.remove(2); // 返回 false,表示集合中不存在 2
randomSet.insert(2); // 向集合中插入 2 返回 true ,集合現在包含 [1,2]
randomSet.getRandom(); // getRandom 應隨機返回 1 或 2
randomSet.remove(1); // 從集合中移除 1 返回 true 。集合現在包含 [2]
randomSet.insert(2); // 2 已在集合中,所以返回 false
randomSet.getRandom(); // 由于 2 是集合中唯一的數字,getRandom 總是返回 2提示:
-231 <= val <= 231 - 1
最多進行 2 * 105 次 insert , remove 和 getRandom 方法調用
當調用 getRandom 方法時,集合中至少有一個元素

解題思路:

  • 1、審題:實現時間復雜度O(1)的哈希表,包含操作插入,刪除,和隨機獲取內部數據
  • 2、解題:該題要實現哈希表的功能,主要要求是時間復雜度為O(1)
  • 插入操作:
    • 使用動態數組vector保存插入后的數據,這樣可以隨機訪問數組內的元素
  • 刪除操作:
    • 要實現數據的刪除,需要先知道該數值在數組內的下標位置,可以使用map數據結構保存,key為數值,value為該數值在數組中的下標位置
    • 這樣就可以通過數值獲取到對應保存的下標位置,
    • 還有一個問題是數組中元素刪除,需要將后面部分元素進行整體移動,時間復雜度為O(n)
    • 要實現數組元素刪除時間復雜度為O(1),可將當前需要刪除的元素與數組尾部元素進行交換,然后直接刪除數組尾部的元素
  • 隨機獲取操作:
    • 使用random隨機獲取數組內的某一個元素

代碼實現:

class RandomizedSet
{
public:RandomizedSet(){}bool insert(int val){if (arrLocationMap.find(val) != arrLocationMap.end()) // 已經包含了{return false;}// 加入到數組和哈希表中arrLocationMap[val] = array.size();array.push_back(val);return true;}bool remove(int val){// 先判斷數組中是否包含該數值if (arrLocationMap.find(val) == arrLocationMap.end()) // 不包含{return false;}// print();// 找到要刪除原始的下標位置int removeIndex = arrLocationMap[val];// 與數組最后元素交換int size = array.size();int removeVal = array[removeIndex];int tailVal = array[size - 1];arrLocationMap[tailVal] = removeIndex;array[removeIndex] = tailVal;array[size - 1] = removeVal;// 刪除數組最后一個元素array.pop_back();arrLocationMap.erase(val);return true;}/** Get a random element from the set. */int getRandom(){// 使用mt引擎std::mt19937 generate(rd());// 創建分布std::uniform_int_distribution<int> dist(0, array.size() - 1);int index = dist(generate);return array[index];}private:std::vector<int> array;std::map<int, int> arrLocationMap; // 保存數組元素,和對應的數組下標std::random_device rd;             // 初始化隨機數生成數
};

3、總結

  • 普通的map哈希表結構為數組與鏈表組合,插入與獲取數據操作,需要遍歷鏈表,時間復雜度為O(n)
  • 要設計O(1)時間復雜度的哈希表,可使用數組進行插入與獲取數據,時間復雜度為O(1),因為數組可通過下標索引操作
  • 而數組的刪除操作,可利用交換處理,轉變為最終刪除數組尾部元素,只是要知道刪元素的位置所在,所以需要一個map值保存每個元素在數組中的下標位置。
  • map操作方法,find為查詢元素是否存在,erase為刪除元素操作。

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

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

相關文章

某光伏電力監控系統網絡安全監測項目:智能組網技術優化方案實踐

背景與挑戰隨著光伏電力行業的快速發展&#xff0c;光伏電站的規模和分布范圍日益擴大。電力監控系統作為光伏電站的核心平臺&#xff0c;其網絡安全直接關系到電力生產的穩定性與可靠性。然而&#xff0c;光伏場站通常分布在偏遠地區&#xff0c;網絡環境復雜&#xff0c;傳統…

GEE訓練教程:基于Landsat 8衛星影像識別并提取指定區域內無云覆蓋的區域多邊形,最終導出為矢量文件

簡介 本文使用Google Earth Engine平臺,通過Landsat 8衛星影像識別并提取指定區域內無云覆蓋的區域多邊形,最終導出為矢量文件。主要步驟包括:定義研究區域、創建云檢測算法、篩選高質量影像、將無云區域轉換為矢量多邊形,并進行可視化檢查和數據導出。 使用Google Earth…

UniApp 頁面通訊方案全解析:從 API 到狀態管理的最佳實踐

在 UniApp 跨端開發中&#xff0c;組件與頁面間的通訊是核心需求。無論是父子組件交互、跨頁面數據傳遞&#xff0c;還是全局狀態共享&#xff0c;選擇合適的通訊方案直接影響代碼的可維護性和性能。本文將系統對比 uni.$emit 系列 API、狀態管理庫&#xff08;Vuex/Pinia&…

【c++進階系列】:萬字詳解AVL樹(附源碼實現)

&#x1f525; 本文專欄&#xff1a;c &#x1f338;作者主頁&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客勵志語錄&#xff1a; 路在腳下延伸時&#xff0c;不必追問終點何在。你邁出的每一步&#xff0c;都在重新定義世界的邊界 ★★★ 本文前置知識&#xff1a; …

前端日志回撈系統的性能優化實踐|得物技術

一、前言在現代前端應用中&#xff0c;日志回撈系統是排查線上問題的重要工具。然而&#xff0c;傳統的日志系統往往面臨著包體積過大、存儲無限膨脹、性能影響用戶體驗等問題。本文將深入分析我們在dw/log和dw/log-upload兩個庫中實施的關鍵性能優化&#xff0c;以及改造過程中…

【QT隨筆】結合應用案例一文完美概括QT中的隊列(Queue)

【QT隨筆】結合應用案例一文完美概括QT中的隊列&#xff08;Queue&#xff09; 隊列&#xff08;Queue&#xff09;是一種線性數據結構&#xff0c;其核心規則為先進先出&#xff08;FIFO, First-In-First-Out&#xff09;&#xff1a; 新元素在隊尾插入&#xff08;enqueue&a…

At least one <template> or <script> is required in a single file component

環境rspack vue3原因rule 中配置了兩個vue-loader刪掉一個即可。

LangChain實戰(十八):構建ReAct模式的網頁內容摘要與分析Agent

本文是《LangChain實戰課》系列的第十八篇,將深入講解如何構建一個基于ReAct模式的智能網頁內容摘要與分析Agent。這個Agent能夠自主瀏覽網頁、提取關鍵信息、生成智能摘要,并進行深入的內容分析,讓信息獲取和理解變得更加高效。 前言 在信息爆炸的時代,我們每天都需要處理…

debian11 ubuntu24 armbian24 apt install pure-ftpd被動模式的正確配置方法

debian11 ubuntu24 armbian24 apt install pure-ftpd被動模式的正確配置方法 安裝方法請看&#xff1a;https://www.itbulu.com/pure-ftpd.html 疑難問題解決 原本以為配置很簡單的&#xff0c;無非是修改 ForcePassiveIP MinUID PassivePortRange PureDB這幾個配置項就行了…

量化金融|基于算法和模型的預測研究綜述

一、研究背景與發展歷程??1.??量化投資理論演進???奠基階段&#xff08;1950s-1960s&#xff09;??&#xff1a;Markowitz均值方差理論&#xff08;1952&#xff09;、CAPM模型&#xff08;1964&#xff09;奠定現代量化投資基礎?衍生品定價&#xff08;1970s-1980s&…

從零開始的云計算生活——第六十天,志在千里,使用Jenkins部署K8S

一.安裝kubectl1、配置yum源cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/ enabled1 gpgcheck1 gpgkeyhttps://mirrors.aliyun.com/kubernetes-new/core/sta…

無人機電壓模塊技術剖析

無人機電源模塊的基本運行方式無人機電壓模塊的核心任務是對動力電源&#xff08;通常是鋰電池&#xff09;進行轉換、調節和分配&#xff0c;為飛控、圖傳、攝像頭、舵機等各個子系統提供穩定可靠的電能。其運行方式可以概括為&#xff1a;電壓轉換與調控&#xff1a;無人機動…

MATLAB基于GM(灰色模型)與LSTM(長短期記憶網絡)的組合預測方法

一、GM與LSTM的基本原理及互補性 1. GM模型的核心特點基本原理&#xff1a;通過累加生成&#xff08;AGO&#xff09;將原始無序序列轉化為具有指數規律的光滑序列&#xff0c;建立一階微分方程&#xff08;如GM(1,1)&#xff09;進行預測。其數學形式為&#xff1a; dx(1)dtax…

【菜狗每日記錄】啟發式算法、傅里葉變換、AC-DTC、Xmeans—20250909

&#x1f431;1、啟發式算法 ① 定義 ② 特點 ③ 案例 &#x1f431;2、快速傅里葉變換FFT ① DFT離散傅里葉變換 ② FFT快速傅里葉變換 &#x1f431;3、AC-DTC聚類 &#x1f431;4、Xmeans &#x1f431;1、啟發式算法 啟發式算法是和最優化算法相對的。 一般而言&am…

Axure移動端選擇器案例:多類型選擇器設計與動態效果實現

在移動端交互設計中&#xff0c;選擇器是用戶輸入的核心組件。Axure移動端高保真元件庫提供了四種關鍵選擇器解決方案&#xff0c;通過動態效果提升操作真實感&#xff1a; 預覽地址&#xff1a;Axure 1. 基礎選擇器 采用底部彈窗設計&#xff0c;支持單選項快速選擇。點擊觸發…

Spring Boot圖片驗證碼功能實現詳解 - 從零開始到完美運行

Spring Boot圖片驗證碼功能實現詳解 - 從零開始到完美運行 &#x1f4d6; 前言 大家好&#xff01;今天我要和大家分享一個非常實用的功能&#xff1a;Spring Boot圖片驗證碼。這個功能可以防止惡意攻擊&#xff0c;比如暴力破解、刷票等。我們實現的是一個帶有加減法運算的圖片…

HarmonyOS實現快遞APP自動識別地址

? 大家好&#xff0c;我是潘Sir&#xff0c;持續分享IT技術&#xff0c;幫你少走彎路。《鴻蒙應用開發從入門到項目實戰》系列文章持續更新中&#xff0c;歡迎關注&#xff01; 隨著鴻蒙&#xff08;HarmonyOS&#xff09;生態發展&#xff0c;越來越多的APP需要進行鴻蒙適…

CUDA編程13 - 測量每個Block的執行時間

一:概述 GPU 程序性能不是靠 CPU 那樣的“順序執行”來衡量的,而是靠線程塊(block)和多處理器(SM)利用率。每個 block 在 GPU 的不同多處理器上執行,順序不確定。傳統的 kernel 總體計時(比如 cudaEvent 計時整個 kernel)只能知道總時間,無法分析哪個 block 慢,為什…

敏捷開發-Scrum(下)

Scrum 核心構成&#xff1a;團隊、事件與工件的協同價值體系 在 Scrum 框架中&#xff0c;“團隊、事件、工件” 并非孤立的模塊&#xff0c;而是相互咬合的有機整體&#xff1a;Scrum 團隊是價值交付的執行核心&#xff0c;Scrum 事件是節奏把控與反饋調整的機制載體&#xff…

LeetCode 單調棧 739. 每日溫度

739. 每日溫度給定一個整數數組 temperatures &#xff0c;表示每天的溫度&#xff0c;返回一個數組 answer &#xff0c;其中 answer[i] 是指對于第 i 天&#xff0c;下一個更高溫度出現在幾天后。如果氣溫在這之后都不會升高&#xff0c;請在該位置用 0 來代替。 示例 1: 輸入…