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.mzph.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…

国网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…

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…

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…

Keil手动安装编译器V5版本

V5编译器下载&#xff1a;免积分下载 新版的keil不会自动帮你安装V5版本的编译器&#xff0c;但是很多教程很多比赛所用单片机都是V5的编译器&#xff0c;所以用来开以前的或者开源的很多东西编译直接一大堆报错。 吐槽说完了接下来教你怎么解决 打开installer&#xff08;在…

搞大事!法国邀请芬兰公司建量子工厂

法国当地时间5月13日&#xff0c;法国总统马克龙宣布启动2024年度“选择法国”&#xff08;Choose France&#xff09;商业峰会。今年峰会召开前&#xff0c;法国赢得了创纪录的150亿欧元外国投资承诺&#xff0c;覆盖从人工智能到制药和能源等领域。 而涉及到量子领域最重磅的…

el-select下拉框 添加 el-checkbox 多选框,支持全选、取消全选

el-select下拉框 添加 el-checkbox 多选框&#xff0c;支持全选、取消全选 前言一、实现思路二、实现代码1.模板代码2. css 样式3.js 代码 DEMO 演示总结 前言 实现效果预览 提示&#xff1a;本内容基于element-ui 组件实现&#xff0c;如果使用其他组件库、可参考下面实现方…

关于GitHub仓库建立及提交问题

文章目录 前言GitHub仓库创建token令牌的获取GitHub克隆到本地GitHub上传文件 前言 为了整一个GitHub仓库然后上传文件&#xff0c;笔者看了不下100篇博客&#xff0c;20段教程&#xff0c;最后在两位大佬的帮助下&#xff0c;才整明白了&#x1f62d; 先提前说一嘴从 2021年8月…

网络爬虫安全:90后小伙,用软件非法搬运他人原创视频被判刑

目录 违法视频搬运软件是网络爬虫 如何发现偷盗视频的爬虫&#xff1f; 拦截违法网络爬虫 央视《今日说法》栏目近日报道了一名程序员开发非法视频搬运软件获利超700多万&#xff0c;最终获刑的案例。 国内某知名短视频平台报警称&#xff0c;有人在网络上售卖一款视频搬运…