【算法學習】哈希表篇:哈希表的使用場景和使用方法

算法學習:

https://blog.csdn.net/2301_80220607/category_12922080.html?spm=1001.2014.3001.5482

前言:

在之前學習數據結構時我們就學習了哈希表的使用方法,這里我們主要是針對哈希表的做題方法進行講解,都是leetcode上的經典題,各位可以自己做一遍再來看一下,主要抽取了幾個經典的題

目錄

1. 哈希表的基礎知識

1.1 哈希表是什么

1.2 哈希表的作用

1.3 什么時候用哈希表

1.4 哈希表的應用場景

2. 哈希表經典例題

2.1 兩數之和

2.2 存在重復元素||

2.3 字母異位詞分組

3. 總結


1. 哈希表的基礎知識

1.1 哈希表是什么

簡單點來說哈希表就是一個存儲數據的容器,但是能夠對出現的數據進行標記

1.2 哈希表的作用

能夠實現快速查找指定的數據,時間復雜度往往為O(1)

1.3 什么時候用哈希表

頻繁的查找數據時

1.4 哈希表的應用場景

1. 直接使用哈希表這個數據類型

2. 在合適的場景使用數組來模擬哈希表

解釋:

2、3:當我們需要頻繁查找數據的時候我們就可以想到要用哈希表,哈希表的時間復雜度為o(1),空間復雜度為o(n)同時也要考慮是否可以用二分,二分時間復雜度為o(logn),也非常快,而且二分沒有時間開銷
4:除了之間使用函數提供給我們的哈希表外,我們也可以用數組模擬創建一個簡易的哈希表,但這種只適用于元素少的情況,比如讓我們統計字符串中各字符出現次數,我們就可以用數組 int hash[26]模擬一下

2. 哈希表經典例題

2.1 兩數之和

1. 兩數之和

給定一個整數數組?nums?和一個整數目標值?target,請你在該數組中找出?和為目標值?target? 的那?兩個?整數,并返回它們的數組下標。

你可以假設每種輸入只會對應一個答案,并且你不能使用兩次相同的元素。

你可以按任意順序返回答案。

示例 1:

輸入:nums = [2,7,11,15], target = 9
輸出:[0,1]
解釋:因為 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

輸入:nums = [3,2,4], target = 6
輸出:[1,2]

示例 3:

輸入:nums = [3,3], target = 6
輸出:[0,1]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只會存在一個有效答案

算法原理:

解法一:暴力枚舉

在這個暴力枚舉中我們來考慮一種新的枚舉思路

比如本題,按照之前的枚舉策略,我們是要讓當前位置(cur)與后面位置的數字依次相加,然后看是否有滿足條件的數字

現在我們來看一種新的枚舉思路,就是讓所有位置的數字,與它前面位置的數字相加,然后判斷是否有滿足條件的兩個數字這樣的思路也能保證讓所有的數兩兩相加,而且在處理一些細節上更有優勢,尤其是本題,下面我們結合本題來感受一下

比如上面我們提到的這個隊列,按照原來的思路,我們先來找一下2后面是否有合適的數字,使得2與其相加等于target,為了減小時間復雜度我們這里要用哈希表的方法,哈希表中存的值是數組中元素和對應的下標<nums[i,i>,但是如果我們是找當前元素后面的值時,我們就需要先提前將數組中所有數字及它們對應的下標先放入哈希表中,但這就會導致一些問題

比如這樣一個數組和target值,如果我們按照原策略先將所有數字和對應下標放入哈希表中的話因為有兩個3,在第一個3及它對應的下標放入哈希表中后,當放第二個3及它對應的下標時,就會把前一個存的3的下標給覆蓋掉,所以我們還需要額外的操作對重復的數字的多個下標進行保存

但是如果我們采取的策略二,我們創建哈希表的時機就會發生一些變化,比如我們現在位置在2,我們是要從前面的位置找合適的數,前面沒有數,所以哈希表中自然也沒有,然后我們可以將2的值及它的下標放入哈希表中,同時讓cur++,這樣做的優化點是什么呢?

此時假如我們再遇到上面的情況(兩個3),我們在第一個3時査找它前面是否有合適的數(前面的數己經放入哈希表了)時,會發現沒有,然后我們把它放入哈希表中,然后到第二個3,我們發現哈希表中hash[target-3]存有一個下標,我們就找到滿足條件的下標了

假如我們現在的target不是6,而是14,那我們在經過第二個3后,雖然會把哈希表中3對應的下標替換掉,但是仍不影響最終結果

思考一下:其實第二種策略比第一種策略的優化之處就是,策略二在替換一個數的坐標之前,是事先知道這個數字兩兩相加不滿足條件的,所以保留一個與其它數字相加即可,而第一個數字則是在沒考慮這種情況之前就只把重復數字只留下一個

代碼實現:

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

2.2 存在重復元素||

219. 存在重復元素 II

給你一個整數數組?nums?和一個整數?k?,判斷數組中是否存在兩個?不同的索引?i?和?j?,滿足?nums[i] == nums[j]?且?abs(i - j) <= k?。如果存在,返回?true?;否則,返回?false?。

示例?1:

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

示例 2:

輸入:nums = [1,0,1,1], k = 1
輸出:true

示例 3:

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

提示:

  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • 0 <= k <= 105

這道題就可以用上面的思路來解,挺簡單的,可以練練手

代碼實現:

class Solution {
public:bool containsNearbyDuplicate(vector<int>& nums, int k) {unordered_map<int,int> hash;for(int i=0;i<nums.size();i++){if(hash.count(nums[i])&&i-hash[nums[i]]<=k) return true;hash[nums[i]]=i;}return false;}
};

2.3 字母異位詞分組

49. 字母異位詞分組

給你一個字符串數組,請你將?字母異位詞?組合在一起。可以按任意順序返回結果列表。

字母異位詞?是由重新排列源單詞的所有字母得到的一個新單詞。

示例 1:

輸入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
輸出: [["bat"],["nat","tan"],["ate","eat","tea"]]

示例 2:

輸入: strs = [""]輸出: [[""]]

示例 3:

輸入: strs = ["a"]輸出: [["a"]]

提示:

  • 1 <= strs.length <= 104
  • 0 <= strs[i].length <= 100
  • strs[i]?僅包含小寫字母

算法原理:

解釋:

這道題就很考驗我們對哈希表的使用,我們在這里創建的哈希表類型是一個<string,vector<string>>類型的哈希表,我們要做的是把所有的字母異位詞放在一起,那么我們首先就需要判斷哪些詞是字母異位詞,在這里我們有一個很巧的方法去判斷,我們可以把這些字符串排序,字母異位詞排序后是相等的,就如左邊那樣(“eat",“tea“排序后都是“aet"),然后讓排序后的字符串作為key值,字母異位詞放在同一個key值后,最后再從哈希表中把這些字符串數組提取出來即可

代碼實現:

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {unordered_map<string,vector<string>> hash;for(int i=0;i<strs.size();i++){string tmp=strs[i];sort(strs[i].begin(),strs[i].end());hash[strs[i]].push_back(tmp);}vector<vector<string>> ret;for(auto& [x,y]:hash)ret.push_back(y);return ret;}
};

3. 總結

以上就是幾個關于哈希表的經典例題,都不算難,哈希表在算法題里出現的比例還是非常高的,一般都是作為一種數據類型存在的,掌握還是很有必要的

本篇筆記:

感謝各位大佬觀看,創作不易,還望各位大佬點贊支持!!

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

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

相關文章

Java 中如何實現自定義類加載器,應用場景是什么?

在 Java 中&#xff0c;可以通過繼承 java.lang.ClassLoader 類來實現自定義類加載器。自定義類加載器可以控制類的加載方式&#xff0c;實現一些特殊的應用場景。 實現自定義類加載器的步驟&#xff1a; 繼承 java.lang.ClassLoader 類。 重寫 findClass(String name) 方法 …

信創開發中跨平臺開發框架的選擇與實踐指南

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#, Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開…

WebRTC 服務器之Janus架構分析

1. Webrtc三種類型通信架構 1.1 1 對 1 通信 1 對 1 通信模型設計的主要?標是盡量讓兩個終端進?直聯&#xff0c;這樣即可以節省服務器的資源&#xff0c;?可以提? ?視頻的服務質量。WebRTC ?先嘗試兩個終端之間是否可以通過 P2P 直接進?通信&#xff0c;如果?法直接…

數字化轉型進階:26頁華為數字化轉型實踐分享【附全文閱讀】

本文分享了華為數字化轉型的實踐經驗和體會。華為通過數字化變革,致力于在客戶服務、供應鏈、產品管理等方面提高效率,并把數字世界帶入每個組織,構建萬物互聯的智能世界。華為的數字化轉型愿景是成為行業標桿,通過推進數字化戰略、構建面向業務數字化轉型的IT組織陣型、堅…

Hal庫下備份寄存器

首先要確保有外部電源給VBAT供電 生成后應該會有這兩個文件&#xff08;不知道為什么生成了好幾次都沒有&#xff0c;復制工程在試一次就有了&#xff09; 可以看到stm32f407有20個備份寄存器 讀寫函數 void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t Backup…

使用 Vue3 + Webpack 和 Vue3 + Vite 實現微前端架構(基于 Qiankun)

在現代前端開發中&#xff0c;微前端架構逐漸成為一種流行的解決方案&#xff0c;尤其是在大型項目中。通過微前端&#xff0c;我們可以將一個復雜的單體應用拆分為多個獨立的小型應用&#xff0c;每個子應用可以獨立開發、部署和運行&#xff0c;同時共享主應用的基礎設施。本…

【c++】【STL】list詳解

目錄 list的作用list的接口構造函數賦值運算符重載迭代器相關sizeemptyfrontbackassignpush_frontpop_frontpush_backpop_backinserteraseswapresizeclearspliceremoveremove_ifuniquemergesortreverse關系運算符重載&#xff08;非成員函數&#xff09; list的模擬實現結點類迭…

Redis持久化:

什么是Redis持久化&#xff1a; Redis 持久化是指將 Redis 內存中的數據保存到硬盤等持久化存儲介質中&#xff0c;以便在 Redis 服務器重啟或出現故障時能夠恢復數據&#xff0c;保證數據的可靠性和持續性。Redis 提供了兩種主要的持久化方式&#xff1a;RDB&#xff08;Redi…

VBA 64位API聲明語句第009講

跟我學VBA&#xff0c;我這里專注VBA, 授人以漁。我98年開始&#xff0c;從源碼接觸VBA已經20余年了&#xff0c;隨著年齡的增長&#xff0c;越來越覺得有必要把這項技能傳遞給需要這項技術的職場人員。希望職場和數據打交道的朋友&#xff0c;都來學習VBA,利用VBA,起碼可以提高…

在pycharm profession 2020.3將.py程序使用pyinstaller打包成exe

一、安裝pyinstaller 在pycharm的項目的Terminal中運行pip3 install pyinstaller即可。 安裝后在Terminal中輸入pip3 list看一下是否成功 二、務必在在項目的Terminal中輸入命令打包&#xff0c;命令如下&#xff1a; python3 -m PyInstaller --noconsole --onefile xxx.py …

Unity SpriteRenderer(精靈渲染器)

&#x1f3c6; 個人愚見&#xff0c;沒事寫寫筆記 &#x1f3c6;《博客內容》&#xff1a;Unity3D開發內容 &#x1f3c6;&#x1f389;歡迎 &#x1f44d;點贊?評論?收藏 &#x1f50e;SpriteRenderer:精靈渲染器 &#x1f4a1;Sprite Renderer是精靈渲染器&#xff0c;所有…

2.LED燈的控制和按鍵檢測

目錄 STM32F103的GPIO口 GPIO口的作用 GPIO口的工作模式 input輸入檢測 -- 向內檢測 output控制輸出 -- 向外輸出 寄存器 寄存器地址的確定 配置GPIO口的工作模式 時鐘的開啟和關閉 軟件編程驅動 LED 燈 硬件 軟件 軟件編程驅動 KEY 按鍵 硬件 軟件 按鍵消抖 代碼 STM32F…

Flink 的狀態機制

在實時流處理領域&#xff0c;狀態管理是構建復雜業務邏輯的核心能力。Apache Flink 通過統一的狀態抽象和高效的容錯機制&#xff0c;為開發者提供了從毫秒級窗口聚合到 TB 級歷史數據關聯的全場景支持。本文將深入剖析 Flink 狀態機制的底層原理&#xff0c;結合實際案例展示…

【查看.ipynp 文件】

目錄 如何打開 .ipynb 文件&#xff1f; 如果確實是 .ipynp 文件&#xff1a; .ipynp 并不是常見的 Jupyter Notebook 文件格式。通常&#xff0c;Jupyter Notebook 文件的擴展名是 .ipynb&#xff08;即 Interactive Python Notebook&#xff09;。如果你遇到的是 .ipynb 文…

Runnable組件重試機制降低程序錯誤率

一、LangChain 重試機制深度解析 當構建生產級AI應用時&#xff0c;with_retry() 機制可有效提升系統容錯性&#xff0c;典型應用場景包括&#xff1a; API調用頻率限制時的自動恢復模型服務臨時不可用的故障轉移網絡波動導致的瞬時異常處理 參數詳解與配置策略 1. 參數配置…

k8s筆記——kubebuilder工作流程

kubebuilder工作流程 Kubebuilder 工作流程詳解 Kubebuilder 是 Kubernetes 官方推薦的 Operator 開發框架&#xff0c;用于構建基于 Custom Resource Definitions (CRD) 的控制器。以下是其核心工作流程的完整說明&#xff1a; 1. 初始化項目 # 創建項目目錄 mkdir my-opera…

Java框架“若依RuoYi”前后端分離部署

運行環境 Eclipse IDE for Enterprise Java and Web Developers 下載Eclipse解壓Eclipse到文件夾 Maven 下載Maven解壓Maven到文件夾配置環境變量MAVEN_HOME為Maven安裝位置配置環境變量path為%MAVEN_HOME%\bin Redis 下載Redis解壓Redis到文件夾配置環境變量path為Redis安裝位…

游戲引擎學習第249天:清理調試宏

歡迎大家&#xff0c;讓我們直接進入調試代碼的改進工作 接下來&#xff0c;我們來看一下上次停留的位置。如果我沒記錯的話&#xff0c;上一場直播的結尾我有提到一些我想做的事情&#xff0c;并且在代碼中留下了一個待辦事項。所以也許我們今天首先做的就是解決這個問題。但…

二極管反向恢復的定義和原理

二極管的反向恢復定義 二極管的反向恢復是指二極管從正向導通狀態切換到反向阻斷狀態時&#xff0c;電流從正向變為負向并最終回到零所需的時間。具體過程如下&#xff1a; 正向導通&#xff1a;當二極管正向偏置時&#xff0c;電流可以順利通過&#xff0c;此時二極管處于導…

音視頻開發技術總結報告

音視頻開發技術總結報告 一、音視頻開發基礎 1、音頻基礎 聲音原理 聲波特性&#xff1a;頻率、振幅、波長人耳聽覺范圍&#xff1a;20Hz-20kHz聲音三要素&#xff1a;音調、音量、音色 數字音頻基礎 采樣率&#xff1a;常見44.1kHz、48kHz、96kHz量化位數&#xff1a;8bit、…