哈希表篇三
哈希表篇(三)
一、202. 快乐数
思路分析
由题意本题有两个重要点:
- 如何对数的每一位求该位置上的平方和
- 如果最后不是1,则会无限循环,导致一定会有sum重复
对于问题1,则我们选择对取数值各个位上的单数操作,通过对取值数的模10操作,达到取每一位的数的平方和。
对于问题2,则与哈希表相关——当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法,因此判断sum是否出现重复,就用到了unordered_set
(出现重复元素即返回false)
代码
class Solution {
public:
int getsum(int n){
int sum = 0;
while(n){//当n为0时跳出循环
sum += (n%10)*(n%10);
n /= 10;//从取该数的个位开始至十位百位往上
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> set;
while(1){//这是一个死循环,无限循环下去,除了return
int sum = getsum(n);
if(sum == 1){
return true;
}
if(set.find(sum)!=set.end()){
return false;
}
else{
set.insert(sum);
}
n = sum;
}
}
};
二、1. 两数之和
思路解析
1、暴力解法
对于寻找两数之和的数组问题,最简单直接的就是两层for循环,在逐次找到目标值后进行跳出即可。
代码
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 {};
}
};
2、哈希表的使用
由于本道题目要求是一维进行加法计算匹配,一维进行输出下标,所以则要使用map
使用数组和set来做哈希法的局限。
- 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
- set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。
map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下标。
C++中是map介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Qxq3y2t-1651201019490)(https://s2.loli.net/2022/04/28/S7E84AI6triwsFm.png)]
std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。
由图可知:std::map 和std::multimap 的key也是有序的**(这个问题也经常作为面试题,考察对语言容器底层的理解)**
这道题目中并不需要key有序,选择std::unordered_map 效率更高!
代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
std::unordered_map<int, int>map;
for(int i = 0; i < nums.size(); i++){
auto cur = map.find(target - nums[i]);
if(cur != map.end()){
return {cur->second, i};
}
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};
代码解释
map的常用函数
at 返回索引处元素的引用
begin 返回指向容器头的迭代器
cbegin 返回指向容器头的迭代器-const
bucket 返回key所对应的桶(bucket)的编号
bucket_count 返回容器中桶(bucket)的个数
bucket_size 返回对应桶(bucket)中的元素个数
cend 返回指向容器尾元素后一个位置的迭代器 - const
clear 清空容器
count 返回key对应元素的个数,因为unordered_map不允许有重复key,所以返回0或1emplace move
emplace_hint 过迭代器位置进行emplace, 因此可以从参数位置开始搜索,速度更快
empty 判断容器是否为空
end 返回指向容器尾的迭代器
equal_range
erase 删除元素
find 查找
get_allocator
hash_function
insert 插入元素
key_eq
load_factor 返回容器当前负载系数
max_bucket_count 返回容器所能包含的桶的最大数量
max_load_factor 容器最大负载系数max_size 返回容器可以容纳的最大元素数
operator= 重载运算符 =
operator[] 重载运算符 [],通过索引可返回对应元素的引用
rehash 参数n大于当前桶数,rehash,否则容器无变化
reserve n大于bucket_count*max_load_factor,rehash,否则容器无变化
size 返回容器中元素个数
swap 当前容器与参数容器中元素交换
- 直接返回{},提高速率
- it!=map.end()即能找到,则return
- 没找到,就将这个数以及对应的位置存进哈希表