Leetcode---1.兩數之和 (詳解加哈希表解釋和使用)

文章目錄

    • 題目 [兩數之和](https://leetcode.cn/problems/two-sum/)
      • 方法一:暴力枚舉
      • 代碼
      • 方法二:哈希表
      • 代碼
    • 哈希表
      • 哈希表的基本概念
        • 哈希函數(Hash Function):
        • 沖突(Collision):
        • 鏈地址法(Chaining):
        • 開放地址法(Open Addressing):
      • 哈希表的操作
        • 插入(Insert):
        • 查找(Search):
        • 刪除(Delete):
      • 哈希表的優點和缺點
        • 優點:
        • 缺點:
      • 基本用法
      • 示例代碼
        • 示例 1:計數字符出現次數
        • 示例 2:兩數之和問題
      • 注意事項
        • 性能
        • 哈希函數
        • 內存開銷

題目 兩數之和

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

你可以假設每種輸入只會對應一個答案。但是,數組中同一個元素在答案里不能重復出現。

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

在這里插入圖片描述

方法一:暴力枚舉

思路及算法

最容易想到的方法是枚舉數組中的每一個數 x,尋找數組中是否存在 target - x。

當我們使用遍歷整個數組的方式尋找 target - x 時,需要注意到每一個位于 x 之前的元素都已經和 x 匹配過,因此不需要再進行匹配。而每一個元素不能被使用兩次,所以我們只需要在 x 后面的元素中尋找 target - x。

代碼

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

復雜度分析

時間復雜度:O(N2),其中 N 是數組中的元素數量。最壞情況下數組中任意兩個數都要被匹配一次。

空間復雜度:O(1).

方法二:哈希表

思路及算法

注意到方法一的時間復雜度較高的原因是尋找 target - x 的時間復雜度過高。因此,我們需要一種更優秀的方法,能夠快速尋找數組中是否存在目標元素。如果存在,我們需要找出它的索引。

使用哈希表,可以將尋找 target - x 的時間復雜度降低到從 O(N) 降低到 O(1)。

這樣我們創建一個哈希表,對于每一個 x,我們首先查詢哈希表中是否存在 target - x,然后將 x 插入到哈希表中,即可保證不會讓 x 和自己匹配。

代碼

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hashtable;for (int i = 0; i < nums.size(); ++i) {auto it = hashtable.find(target - nums[i]);if (it != hashtable.end()) {return {it->second, i};}hashtable[nums[i]] = i;}return {};}
};

復雜度分析

時間復雜度:O(N),其中 N 是數組中的元素數量。對于每一個元素 x,我們可以 O(1) 地尋找 target - x。

空間復雜度:O(N),其中 N 是數組中的元素數量。主要為哈希表的開銷。

哈希表

哈希表的基本概念

哈希函數(Hash Function):
  1. 哈希函數將輸入的鍵轉換為哈希碼,這個哈希碼通常是一個整數。
  2. 哈希碼用于確定鍵值對在哈希表中的存儲位置。
  3. 一個好的哈希函數應當均勻地分布鍵,減少沖突的發生。
沖突(Collision):
  1. 當兩個不同的鍵被哈希函數映射到同一個存儲位置時,稱為沖突。
  2. 處理沖突的方法主要有兩種:鏈地址法(Chaining)和開放地址法(Open Addressing)。
鏈地址法(Chaining):
  1. 每個存儲桶存儲一個鏈表或其他數據結構來處理沖突。
  2. 當沖突發生時,新鍵值對被插入到對應存儲桶的鏈表中。
開放地址法(Open Addressing):
  1. 當沖突發生時,尋找另一個空的存儲桶來存儲沖突的鍵值對。
  2. 常見的開放地址法包括線性探測(Linear Probing)、二次探測(Quadratic Probing)和雙重散列(Double Hashing)。

哈希表的操作

插入(Insert):
  1. 計算鍵的哈希碼,找到對應的存儲桶。
  2. 如果沒有沖突,直接插入。
  3. 如果有沖突,根據沖突解決策略進行處理(例如鏈地址法或開放地址法)。
查找(Search):
  1. 計算鍵的哈希碼,找到對應的存儲桶。
  2. 在存儲桶中查找鍵值對。
  3. 如果使用鏈地址法,可能需要遍歷鏈表。
刪除(Delete):
  1. 計算鍵的哈希碼,找到對應的存儲桶。
  2. 在存儲桶中查找并刪除鍵值對。
  3. 如果使用鏈地址法,可能需要遍歷鏈表。

哈希表的優點和缺點

優點:
  1. 快速查找、插入和刪除: 平均情況下,這些操作的時間復雜度都是 O(1)。
  2. 實現簡單: 相對于平衡樹等復雜數據結構,哈希表的實現較為簡單。
缺點:
  1. 需要處理沖突: 盡管沖突不可避免,但沖突處理機制(如鏈地址法或開放地址法)會影響性能。
  2. 內存消耗: 哈希表通常需要額外的內存來存儲鏈表或解決沖突,這在存儲空間有限的情況下可能是個問題。
  3. 無法有序遍歷: 哈希表中的元素沒有特定順序,因此不能按順序遍歷所有鍵值對。

基本用法

在C++中,unordered_map 是標準庫(STL)中的一種關聯容器,提供了鍵值對的哈希表實現。下面是一些常見的操作:

  1. 引入頭文件
#include <unordered_map>
  • 在使用 unordered_map 之前,需要引入 <unordered_map> 頭文件。
  1. 聲明一個哈希表
std::unordered_map<int, int> hashtable;
  • 聲明一個鍵為 int,值也為 int 的哈希表。
  1. 插入元素
hashtable[1] = 100;
hashtable.insert({2, 200});
  • 使用 [] 操作符或 insert 方法插入鍵值對。
  1. 訪問元素
int value = hashtable[1];
auto it = hashtable.find(2);
if (it != hashtable.end()) {std::cout << "Found: " << it->second << std::endl;
}
  • 使用 [] 操作符訪問元素或使用 find 方法查找元素。
  1. 刪除元素
hashtable.erase(1);
  • 使用 erase 方法刪除鍵值對。
  1. 遍歷哈希表
for (const auto& pair : hashtable) {std::cout << pair.first << ": " << pair.second << std::endl;
}

使用范圍 for 循環遍歷哈希表中的所有鍵值對。

示例代碼

下面是一些具體示例,展示如何使用 unordered_map:

示例 1:計數字符出現次數
#include <unordered_map>
#include <iostream>
#include <string>int main() {std::string str = "hello world";std::unordered_map<char, int> char_count;// 統計每個字符出現的次數for (char c : str) {if (c != ' ') {char_count[c]++;}}// 輸出字符出現的次數for (const auto& pair : char_count) {std::cout << pair.first << ": " << pair.second << std::endl;}return 0;
}
示例 2:兩數之和問題
#include <unordered_map>
#include <vector>
#include <iostream>std::vector<int> twoSum(const std::vector<int>& nums, int target) {std::unordered_map<int, int> hashtable;for (int i = 0; i < nums.size(); ++i) {int complement = target - nums[i];auto it = hashtable.find(complement);if (it != hashtable.end()) {return {it->second, i};}hashtable[nums[i]] = i;}return {};
}int main() {std::vector<int> nums = {2, 7, 11, 15};int target = 9;std::vector<int> result = twoSum(nums, target);if (!result.empty()) {std::cout << "Indices: " << result[0] << ", " << result[1] << std::endl;} else {std::cout << "No solution found." << std::endl;}return 0;
}

注意事項

性能
  1. unordered_map 提供平均 O(1) 的插入、查找和刪除操作,但在最壞情況下,這些操作可能是 O(n) 的。
  2. 哈希表的性能高度依賴于哈希函數的質量和負載因子(元素數量與桶的數量之比)。
哈希函數
  1. 自定義類型作為鍵時,需要提供自定義的哈希函數和相等函數。
內存開銷
  1. unordered_map 在存儲鍵值對時會使用額外的內存來維護哈希桶。

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

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

相關文章

windows驅動開發-PCI討論(一)

前面描述中斷的時候&#xff0c;我們曾經多次體積PCI&#xff0c;甚至提供了一些PCI的相關知識&#xff0c;但是整個PCI是一個很大的體系&#xff0c;專門記錄這個體系超出了這個系列的范疇&#xff0c;有興趣的可以到PCI官網了解詳細的情況。 但是還是會花費一些時間討論PCI技…

Pytorch入門實戰 P10-使用pytorch實現車牌識別

目錄 前言 一、MyDataset文件 二、完整代碼&#xff1a; 三、結果展示&#xff1a; 四、添加accuracy值 &#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 | 接輔導、項目定制 本周的學習內容是&#xff0…

SEO:搜索引擎蜘蛛名稱UA(user-agent)

最近網站在做統計功能&#xff0c;想著統計下蜘蛛爬行記錄&#xff0c;看看都有哪些搜索引擎蜘蛛經常關顧&#xff0c;故而好進行相應的對策改變。都知道搜索引擎對一個網站很重要,是很多網站重要的流量來源。熟悉各大搜索引擎的蜘蛛就顯得必要。 做SEO優化的通常會說蜘蛛爬得越…

國網698.45報文解析工具

本文分享一個698.45協議的報文解析工具&#xff0c;此報文解析工具功能強大&#xff0c;可以解析多種國網數據協議。 下載鏈接: https://pan.baidu.com/s/1ngbBG-yL8ucRWLDflqzEnQ 提取碼: y1de 主要界面如下&#xff1a; 本工具內置698.45數據協議&#xff0c; 即可調用word…

win編寫bat腳本啟動java服務

新建txt&#xff0c;編寫&#xff0c;前臺啟動&#xff0c;出現cmd黑窗口 echo off start java -jar zhoao1.jar start java -jar zhoao2.jar pause完成后&#xff0c;重命名.bat 1、后臺啟動&#xff0c;不出現cmd黑窗口&#xff0c;app是窗口名稱 echo off start "名…

美團小程序mtgsig1.2逆向

聲明 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包內容、敏感網址、數據接口等均已做脫敏處理&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01;wx a15018601872 本文章未…

VMware虛擬機沒有網,無法設置網絡為橋接狀態

今天需要使用Ubuntu18但現有虛擬機是Ubuntu20&#xff0c;由于硬盤空間不夠大&#xff0c;所以刪除了原來的虛擬機并重新搭建Ubuntu18的環境&#xff0c;然后發現虛擬機沒有網絡&#xff0c;而我之前的虛擬機這一切都是正常的。 在網絡設置里勾選的是橋接模式但無法聯網&#x…

由讀寫arrow引發的對時間時區的思考

arrow是apache開發的一種高壓縮的數據結構&#xff0c;發現用來存儲K線還是很不錯的選擇。 測試用python讀寫很方便&#xff0c;關鍵是足夠小&#xff0c;A股1支票1分鐘的數據&#xff0c;1個月大約是140多K吧。 結果從數據庫取出來存入arrow中&#xff0c;再用C進行讀取&…

Cow Exhibition G的來龍去脈

[USACO03FALL] Cow Exhibition G - 洛谷 曲折經過 爆搜 一開始沒什么好的想法&#xff0c;就針對每頭奶牛去or不去進行了爆搜。 #include <cstdio> #include <algorithm> using namespace std;#define maxn 405 int iq[maxn], eq[maxn]; int ans; int n;void d…

留學資訊 | 2024英國學生簽證申請需要滿足哪些條件?

英國移民局于2020年9月10日發布了《移民規則變更聲明: HC 707》&#xff0c;對學生簽證制度進行了全面改革。該法案于2020年10月5日正式生效。根據此法案&#xff0c;新的學生簽證——The Student and Child Student Routes學生和兒童學生路線&#xff0c;將替代原先的Tier 4學…

短視頻賽道有哪些:成都鼎茂宏升文化傳媒公司

短視頻賽道有哪些&#xff1a;探索多元化的內容領域 隨著科技的飛速發展和人們生活節奏的加快&#xff0c;短視頻已成為現代人生活中不可或缺的一部分。它以其簡短、直觀、易于分享的特點&#xff0c;迅速占領了各個年齡層和社會群體的心智。然而&#xff0c;短視頻的賽道并非…

層次式體系結構概述

1.軟件體系結構 軟件體系結構可定義為&#xff1a;軟件體系結構為軟件系統提供了結構、行為和屬性的高級抽象&#xff0c;由構成系統的元素描述、這些元素的相互作用、指導元素集成的模式以及這些模式的約束組成。軟件體系結構不僅指定了系統的組織結構和拓撲結構&#xff0c;并…

小程序框架是智能融媒體平臺構建的最佳線路

過去5年&#xff0c;媒體行業一直都在進行著信息化建設向融媒體平臺建設的轉變。一些融媒體的建設演變總結如下&#xff1a; 新聞終端的端側內容矩陣建設&#xff0c;如App新聞端&#xff0c;社交平臺上的官方媒體等新聞本地生活雙旗艦客戶端&#xff0c;兼顧主流媒體核心宣傳…

TopOn 正式聚合Kwai 旗下程序化廣告平臺——Kwai Network

**我們非常高興的宣布&#xff0c;TopOn SDK 近日已正式聚合Kwai Network。**作為Kwai 旗下的程序化廣告平臺&#xff0c;Kwai Network 通過優質的變現能力及產品能力&#xff0c;為廣大開發者提供高效及時的服務。 TopOn 聚合平臺與Kwai Network 正式完成接入后&#xff0c;開…

實戰+代碼!Selenium + Phantom JS爬取天天基金數據

功能&#xff1a; 通過程序實現從基金列表頁&#xff0c;獲取指定頁數內所有基金的近一周收益率以及每支基金的詳情頁鏈接。再進入每支基金的詳情頁獲取其余的基金信息&#xff0c;將所有獲取到的基金詳細信息按近6月收益率倒序排列寫入一個Excel表格。 思路&#xff1a; 1.…

vm 虛擬機 Debian12 開啟 root、ssh 登錄功能

前言&#xff0c;安裝的時候語言就選中文就好了。選擇中文&#xff0c;在安裝的時候就可以選擇國內 163 的源。 開啟 ssh 功能 先提權&#xff0c;用 root 賬戶 su安裝 ssh 安裝 ssh-server apt install openssh-server啟動 ssh systemctl start ssh查看 ssh 狀態 systemctl st…

【Flutter 面試題】 如何讓圖片重復堆疊容器?

【Flutter 面試題】 如何讓圖片重復堆疊容器? 文章目錄 寫在前面口述回答補充說明寫在前面 ?? 關于我 ,小雨青年 ?? CSDN博客專家,GitChat專欄作者,阿里云社區專家博主,51CTO專家博主。2023博客之星TOP153。 ???? 正在學 Flutter 的同學,你好! ?? Flutter …

根據web訪問日志,封禁請求量異常的IP,如IP在半小 時后恢復正常則解除封禁

在網絡安全日益受到重視的今天&#xff0c;如何有效防范惡意流量和攻擊成為了每個網站管理員必須面對的問題。惡意流量不僅會影響網站的正常運行&#xff0c;還可能導致服務器崩潰&#xff0c;給網站帶來不可估量的損失。為了應對這一問題&#xff0c;我們特別推出了一款實用的…

u3d的ab文件注意事項

//----------------LoadAllAB.cs--------------------- using System.Collections;using UnityEngine;namespace System.IO{public class LoadAllAB : MonoBehaviour{ //讀取本地string path "Assets/Actors/lznh/ab/animation/t_bl/";// Use this for initiali…

SQL注入之數據庫基礎

數據庫基礎 創建數據庫 create 數據庫名稱;創建表 create table if not exists mobile(ID int(10) primary key auto_increment comment 手機編號 主鍵自增,Brand varchar(50) not null comment 手機品牌 非空約束,Model varchar(50) not null comment 手機型號 非空約束,Pr…