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…

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…