赞
踩
哈希表(Hash Table)也称散列表,是根据关键码值(key, value)而直接进行访问的数据结构。
1、将键值映射为哈希表上具体的索引数字:利用hashCode将键值转化为具体数值(hashcode通过特定编码方式,可以将其他数据格式转化为不同的数值)
2、若hashCode得到的数值大于哈希表的大小:将得到的索引数字对哈希表的大小取模,保证键值一定可以映射到哈希表上。
3、若有不同的键值映射到了同一个索引数值,则产生了哈希冲突。
其中简化代码如下:
- //哈希函数:hash_function
- index_value=hash_function(key); //key是键值
- int hash_function(int key,int hash_size){
- return hash_code(key)%hash_size; //hash_size代表哈希表大小
- }
主要有两种方法:开放地址法和链地址法(也叫拉链法)
1、开放地址法
用开放定址法解决冲突的做法是:当冲突发生时,使用某种探测算法在散列表中寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到。按照探测序列的方法,一般将开放地址法区分为线性探查法、二次探查法、双重散列法等。(要求hash_size一定要大于data_size,要不然哈希表上就没有空置的位置来存放冲突的数据了)
2、拉链法
用拉链法解决冲突的做法是:当冲突发生时,将发生冲突的元素(键值)存储在链表中,可以通过索引找到发生冲突的元素。需要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。
在C++中,set 和 map 分别提供以下三种数据结构,其底层实现以及优劣如下表所示:
- int main()
- {
- //哈希表的初始化及插入
- unordered_map<int, string> hash_map={{ 1, "熊大" },{ 2, "熊二" }};//使用{}赋值
- hash_map[3] = "光头强"; //使用[ ]进行单个插入,若已存在键值3,则赋值修改,若无则插入。
- hash_map.insert(pair<int, string>(4, "拖拉机"));//使用insert和pair插入
- hash_map.emplace(pair<int, string>(5, "树"));//效率比 insert() 方法高
-
- //常见操作
- if(hash_map.find(2)!=hash_map.end()){
- cout<<"找到键值为2的值为"<<hash_map.at(2)<<endl;
- }
- hash_map.erase(2);//删除键值为2的成员
- cout << "hash_map size==" << hash_map.size() << endl;//输出hash_map大小
-
- //遍历输出
- for(auto it=hash_map.begin();it!=hash_map.end();it++){
- cout<<it->first<<" "<<it->second<<endl;
- }
-
- getchar();
- return 0;
- }

- class Solution {
- public:
- int lengthOfLongestSubstring(string s) {
- unordered_set<char>res;
- int left=0,right=0;
- int length=0;
- while(right<s.size()){
- while(res.find(s[right])!=res.end()){//保证滑动窗口内没有重复字母
- res.erase(s[left]);
- left++;
- }
- res.insert(s[right]);
- length=max(length,right-left+1);
- right++;
- }
- return length;
- }
- };

- class Solution {
- public:
- vector<string> letterCombinations(string digits) {
- vector<string> combinations;
- if(digits.empty()){
- return combinations;
- }
- unordered_map<char,string> phonemap={
- {'2',"abc"},
- {'3',"def"},
- {'4',"ghi"},
- {'5',"jkl"},
- {'6',"mno"},
- {'7',"pqrs"},
- {'8',"tuv"},
- {'9',"wxyz"}
- };
- string combination;
- backtrace(phonemap,combinations,digits,0,combination);
- return combinations;
- }
- void backtrace(const unordered_map<char,string>& phonemap,vector<string>& combinations,string& digits,int index,string& combination){
- if(index==digits.length())
- combinations.push_back(combination);
- else{
- char digit=digits[index];
- const string& letters=phonemap.at(digit);
- for(const char& letter:letters){
- combination.push_back(letter);
- backtrace(phonemap,combinations,digits,index+1,combination);
- combination.pop_back();
- }
- }
- }
- };

- class Solution {
- public:
- vector<vector<string>> groupAnagrams(vector<string>& strs) {
- unordered_map<string,vector<string>> hashmap;
- for(string& str:strs){
- string key=str;
- sort(key.begin(),key.end());
- hashmap[key].emplace_back(str);
- }
- vector<vector<string>> res;
- for(auto it=hashmap.begin();it!=hashmap.end();it++){
- res.emplace_back(it->second);
- }
- return res;
- }
- };

- class Solution {
- public:
- unordered_map <char, int> ori, cnt;
- bool check(){
- for(const auto &it:ori){
- if(cnt[it.first]<it.second)
- return false;
- }
- return true;
- }
- string minWindow(string s, string t) {
- if(t.size()>s.size()) return {};
- int left=0,right=-1; //注意right初始化为-1
- int left_out=-1;
- int length=INT_MAX;
-
- string out={};
- for(const auto &it:t){
- ori[it]++;
- }
- while(right<int(s.size())){ //注意int类型转换,因为s.size()类型为unsigned int,right初始化为负数
- right++;
- if(ori.find(s[right])!=ori.end()){
- cnt[s[right]]++;
- }
- while(left<=right&&check()){
- if((right-left+1)<length){
- length=right-left+1; //记录最小串长度
- left_out=left; //记录最小串起始位置
- }
- if(ori.find(s[left])!=ori.end()){
- cnt[s[left]]--;
- }
- left++;
- }
- }
- //cout<<s[right];
- return left_out==-1?out:s.substr(left_out,length);
- }
- };

- class Solution {
- public:
- int longestConsecutive(vector<int>& nums) {
- unordered_set<int> hash;
- for(auto x:nums) hash.insert(x);
- int res=0;
- for(auto x:hash){
- if(!hash.count(x-1)){//找到最小的那个
- int y=x;
- while(hash.count(y+1))y++; //找最大的那个
- res=max(res,y-x+1);
- }
- }
- return res;
- }
- };

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。