目录
[【题目链接】217. 存在重复元素 - 力扣(LeetCode)](#【题目链接】217. 存在重复元素 - 力扣(LeetCode))
[【题目链接】1. 两数之和 - 力扣(LeetCode)](#【题目链接】1. 两数之和 - 力扣(LeetCode))
[【题目链接】49. 字母异位词分组 - 力扣(LeetCode)](#【题目链接】49. 字母异位词分组 - 力扣(LeetCode))
[【题目链接】128. 最长连续序列 - 力扣(LeetCode)](#【题目链接】128. 最长连续序列 - 力扣(LeetCode))
[【题目链接】560. 和为 K 的子数组 - 力扣(LeetCode)](#【题目链接】560. 和为 K 的子数组 - 力扣(LeetCode))
【题目链接】217. 存在重复元素 - 力扣(LeetCode)
cppclass Solution { public: bool containsDuplicate(vector<int>& nums) { unordered_set<int> set; for(int i=0;i<nums.size();i++){ if(set.count(nums[i])) return true; set.insert(nums[i]); } return false; } };**解题思路:**利用哈希集合的无重复元素的性质,将数组依次存入哈希集合中,边存边查是否有重复(当前数组值是否已存入过哈希集合)。
**时间复杂度:**O(n) 每个元素只有一次检查+加入。
**空间复杂度:**O(n) 最坏情况需要存入所有元素才能得到结果。
【题目链接】1. 两数之和 - 力扣(LeetCode)
cppclass Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> map; for(int i=0;i<nums.size();i++){//枚举两个数中靠右侧的数a,维护哈希表存前面的[0,i-1]去找b int a=nums[i]; int b=target-a; if(map.find(b)!=map.end()) return {i,map.find(b)->second}; map[a]=i; } return {}; } };**解题思路:**利用哈希表的快速查找思想,假设b+a=target,此时只需要固定一个,去哈希表找另一个即可。遍历数组中的每个值numsi做一次a(两个数中靠右侧的数),维护一个哈希表来存储已遍历过的元素,对于每个数去哈希表中找是否有目标b。
**时间复杂度:**O(n) 需要遍历一遍所有元素才能得到结果,在哈希表中的都是O(1)。
**空间复杂度:**O(n) 哈希表的构建。
【题目链接】49. 字母异位词分组 - 力扣(LeetCode)
cppclass Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { unordered_map<string,vector<string>> map; for(auto i:strs){ string key=i; sort(key.begin(),key.end()); map[key].push_back(i); } vector<vector<string>> result; for(auto k :map){ result.push_back(k.second); } return result; } };**解题思路:**利用排序+哈希表无重复元素和查找快的性质,维护pair<key, value>哈希表记录字母异位词(两个字符串排序之后相等)<模版, 此模版下排序前的字符串构成的数组>。
**时间复杂度:**O(nklogk),k是所有字符串中最长字符串的长度。 排序、遍历
**空间复杂度:**O(nk) 哈希表存储、排序(临时字符串哈希开销)
【题目链接】128. 最长连续序列 - 力扣(LeetCode)
cppclass Solution { public: int longestConsecutive(vector<int>& nums) { unordered_set<int> set_nums; for(auto i:nums){ set_nums.insert(i); } int max=0; for(auto i:set_nums){ if(!set_nums.count(i-1)){//当前数-1不存在的时候,它是起点才有可能最大 int current=i; int flag=1; while(set_nums.count(current+1)){ current++; flag++; } if(flag>max) max=flag; } } return max; } };**解题思路:**利用哈希集合查找快和无重复元素的优势,以及贪心思想,先将数组存入无重复元素的哈希集合,遍历集合中的每个元素i,看集合中是否存在i+1,...,i+k的值,并统计长度为k+1,过程中保存最长的序列长度。(考虑最优解不可能出现在"数-1"存在的数开头的序列上,可以优化时间,只枚举不存在"数-1"的数为起点)
时间复杂度: O(n) 因为每个元素恰好被访问一次。(
for枚举所有数n次,while循环枚举所有非起点元素,而非起点元素最多也只有n个)**空间复杂度:**O(n) 哈希表存储
【题目链接】560. 和为 K 的子数组 - 力扣(LeetCode)
cppclass Solution { public: int subarraySum(vector<int>& nums, int k) { vector<int> sum_nums; int sum=0; for(auto i:nums){ sum+=i; sum_nums.push_back(sum); } int res=0; unordered_map<double,int> map; map[0]=1; for(auto i:sum_nums){ int target=i-k; if(map.count(target)) res+=map[target]; map[i]++; } return res; } };**解题思路:**利用前缀和+哈希两数之和的思想。问题是找到x1+x2+...+xm=k,子数组的和可以转化为两个前缀和之差,即Si-Sj=k是目标(类似前面两数之和的目标)。枚举靠右的Si,找是否出现过Si-k。维护键值对哈希表记录每个前缀和的出现次数res,即为n个子数组以位置i结尾和为k。
**时间复杂度:**O(n)
**空间复杂度:**O(n)
(一)哈希基础
哈希种类
1、哈希集合(set / unordered_set):只存单个元素,元素本身就是 "唯一标识",没有 first /second,底层红黑树有序,平均时间复杂度O(nlogn)
2、哈希表(map / unordered_map):存 key-value 键值对,元素是 pair,所以才有 k.first(键)、k.second(值),底层哈希映射哈希表无序,平均时间复杂度O(n)
哈希表的特点
哈希表是一种基于哈希函数(Hash Function)的数据结构,用于实现键值对的快速存储和查找。它的主要特点是:
- 快速查找:平均情况下,哈希表的查找、插入和删除操作的时间复杂度都是 O(1)。
- 键值对存储:哈希表存储的是键值对,每个键(Key)唯一对应一个值(Value)。
- 哈希函数:通过哈希函数将键映射到哈希表中的位置,从而实现快速存取。
C++中哈希常见用法总结
哈希集合
#include<unordered_set>
unordered_set<int> set; //哈希集合
set.erase(numsi); //删除数字
set.insert(numsi); //插入数字
①set.count(numsi) ②set.find(b)!=set.end() //是否存在numsi,存在返回true
哈希表
#include<unordered_map>
unordered_map<int,int> map; //哈希表,类型任意
mapb=i; //b对应的值为i
map.erase(b); //删除key为b的对
①map.find(b)!=map.end() ②map.count(b) //目标是否存在
常见坑:
- map.find(b)->second //key为b对应的val
- mapb //若存在key是b,则返回val;不存在,插入新key=b,val=默认构造值,再返回val
- //取出所有的second里的值到result
- for(auto k :map)
- result.push_back(k.second);//k.second取val,k.first取key
(二)补充
#include<bits/stdc++.h> //万能头文件
#include <iostream> //引入输入输出流头文件,C++ 标准输入输出库
cin>>; cout<<x<<endl;
using namespace std; //打开 std 标准命名空间(可以简写不写std::)
排序函数:
#include<algorithm>
sort(key.begin(),key.end());//默认从小到大排序
学习中,诚挚希望有心者指正和交流,经验或者方法都可。