1.两数之和(哈希表)
【题目】
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
【示例】
输入:nums = [3,2,4], target = 6
输出:[1,2]
【菜鸡思路】
如果直接暴力,时间复杂度就是n^2。一开始想的是先排序,排完序就可以分成(默认target是正的)比target大的,比target小的正数,负数三个部分。target=两个小的正数相加 或者 大的和负数相加。如果是两个小的正数,就还是遍历,但这个时候是有序的,当和大于target时可以跳出此时的循环。大的和负的也一样的思路。hh最后发现完全不对,不能排序,排完序下标变了。而且就算是这样也还是n^2。
【累了,以我的知识面,不如直接看看答案】
n^2的病灶:寻找 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 {};}
};
很好,其实我没看太明白。
【先来复习一下哈希表这个无比久远的知识点】
1.哈希函数:从key到value的映射。 value=H(key)。
2.哈希冲突:映射不唯一,不同的key可能对应同一个value。
3.哈希表(unordered_map):
头文件:本名 #include <unordered_map>
定义形式:
模板定义
template < class Key, //键值对中键的类型class T, //键值对中值的类型class Hash = hash<Key>, //容器内部存储键值对所用的哈希函数class Pred = equal_to<Key>, //判断各个键值对键相同的规则class Alloc = allocator< pair<const Key,T> > // 指定分配器对象的类型> class unordered_map;
一般来说,只需要 unordered_map<key的类型,value的类型> 表名
unordered_map<int,int> map={
pair<int,int>(1,3)
};
建立:假如关键字1对应值3
- map[1]=3
- map.insert<make_pair(1,3)>
- map.insert({1,3})
迭代器遍历
for(unordered_map<int,int>::iterator it=map.begin();it!=map.end();it++){
cout<<it->first<<it->second<<endl;
}
auto相当于it的前缀定义
常用成员函数
at(key) | 返回容器中存储的键 key 对应的值,如果 key 不存在,则会抛出 out_of_range 异常。 |
find(key) | 查找以 key 为键的键值对,如果找到,则返回一个指向该键值对的正向迭代器;反之,则返回一个指向容器中最后一个键值对之后位置的迭代器(如果 end() 方法返回的迭代器)。 |
count(key) |
在容器中查找以 key 键的键值对的个数。 |
erase() | 删除指定键值对。 |
clear() | 清空容器,即删除容器中存储的所有键值对。 |
swap() | 交换 2 个 unordered_map 容器存储的键值对,前提是必须保证这 2 个容器的类型完全相等。 |
equal_range(key) | 返回一个 pair 对象,其包含 2 个迭代器,用于表明当前容器中键为 key 的键值对所在的范围。 |
emplace() | 向容器中添加新键值对,效率比 insert() 方法高。 |
emplace_hint() | 向容器中添加新键值对,效率比 insert() 方法高。 |
【简单复习一下再次考虑】
确实哈,改用哈希表之后就只需要遍历1趟这n个数。把target-num[i]当作关键字key,最开始find(key)时,map里啥也没有,就把它自己nums[i]和下标i一起插到map里,不需要再遍历一趟。
【最后再简单复习一下map,hash_map,unordered_map区别】
map:
(适用场景:数据量小于1000或者对内存使用要求比较高)
底层是红黑树,空间复杂度O(n),是随着节点的增加才增加,而查找的时间时间复杂度固定是O(log(n))。
特点:红黑树是一种二叉搜索树,所以从begin()遍历到end()得到的key值是有序的。
hash_map和unordered_map:
(适用场景:数据量大的话并且需要频繁查找)
hash表实现,使用开链法解决冲突问题。非有序。查找时间复杂度O(1)。
unordered_map的链表节点用的是称为bucket(桶)的数据结构。支持string做key,也可以使用复杂的对象作为key。而且现在基本都不用hash_map了。
【感想】
有没有真人带带我啊!麻了。。。
1.两数之和(哈希表)相关推荐
- [leetcode]1.两数之和 + 哈希表:梦开始的地方,英语的abandon
方案一:暴力题解没什么可说的,当然不是面试官想看到的 复杂度分析 时间复杂度:O(N^2),其中 N是数组中的元素数量.最坏情况下数组中任意两个数都要被匹配一次.空间复杂度:O(1). 方案二:直白来 ...
- 两数相加——哈希表算法
力扣刷题总结 一.前言 二.两数相加 1.题意 2.示例 3.题目解析 4.官方题解 思路分析 哈希表算法的优势: 思路及算法: 代码分析 C语言代码实现及详细注释说明: python代码实现及详细注 ...
- 【算法】哈希表 ( 两数之和 )
算法 系列博客 [算法]刷题范围建议 和 代码规范 [算法]复杂度理论 ( 时间复杂度 ) [字符串]最长回文子串 ( 蛮力算法 ) [字符串]最长回文子串 ( 中心线枚举算法 ) [字符串]最长回文 ...
- Two Sum (两数之和) - Hash Table (哈希表)
Two Sum (两数之和) - Hash Table (哈希表) https://leetcode-cn.com/problems/two-sum/ Given an array of intege ...
- 从leetcode1. 两数之和循序渐进(双指针,BST,哈希表)
leetcode1. 两数之和 1.之前只知道桶排序那种标志数组,所以看到第一眼就想到那个方面去了.但在本题数组里面存储某个数出现的次数对该题是没有意义的,应该存储某个数出现的位置. 2.哈希表是优化 ...
- 【LeetCode1】两数之和_哈希表
一.题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入只会对应一个答案.但是 ...
- 算法动画图解:两数之和(哈希表)
更多算法动画图解,长按此链接跳转AppStore 动画 算法动画图解:两数之和(哈希表) 思路 哈希表map用来保存一个数,另一个数在遍历nums的时候和map中的数尝试求和是否为target,如果求 ...
- LeetCode 1. 两数之和【哈希表】
1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入只会对应一个答案 ...
- 两数之和 暴力美学 哈希表
1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标. leetcode 你可以假设每种输入只会对应一个答 ...
- 算法训练Day6 | LeetCode:242. 有效的字母异位词(数组作哈希表);349. 两个数组的交集(Set作哈希表);202.快乐数 (Set作哈希表);1. 两数之和(Map作哈希表)
目录 LeetCode242. 有效的字母异位词 方法:数组作哈希表 1. 思路 2. 代码实现 3. 复杂度分析 4. 思考 Leetcode349. 两个数组的交集 方法一:用Set作HashMa ...
最新文章
- python -- IO多路复用
- Matlab实用程序--图形应用-单个轴窗口显示多个图形
- Linux操作系统下实现远程开机
- weka 学习总结(持续)
- 百年难得一见!阿里园区惊现双月争辉奇观!
- 从html到pug模板,将变量从html-webpack-plugin传递到pug模板
- shell 循环删除进程
- 如何在 Laravel 中 “规范” 的开发验证码发送功能
- 【震撼】《京东技术解密》获众大神集体推荐,4千人10年经验一次放送
- 2. node.js 模块管理机制
- net core获取客户端ip
- 微波工程学习心得(一)D.M.Pozar版
- StretchDIBits函数
- Mac重装系统-使用Mac笔记本制作U盘启动盘
- 概率论得学习整理--番外3:二项式定理和 二项式系数
- 计算机网络安全技术保护措施,计算机网络安全技术保护措施
- 台湾半导体制造商台积电市值首次超越英特尔
- 科技爱好者周刊:第 87 期
- Flutter 无埋点SDK实现
- C#,.net将DataTable转为对应的Model实体类