哈希法
哈希法又称散列法、关键字地址计算法等,相应的表成为哈希表。
哈希法的基本思想:首先在元素的关键字K和元素的位置P之间建立一个对应关系f,使得P=f(K),其中f称为哈希函数。
创建哈希表时,把关键字K的元素直接存入地址为f(K)的单元;查找关键字K的元素利用哈希函数计算出该元素的存储位置P=f(K)
哈希函数的构造方法
哈希函数的构造原则是:函数本身便于计算、计算出来的地址分布均匀(即对任意K,f(K)对应不同地址的概率相等)。常见构造方法:
- 数字分析法
- 平方取中法:
- 分段叠加法:
- 除留余数法:
处理冲突的方法:
当关键字集合很大时,关键字值不同的元素可能会映射到哈希表的同一地址上,即K1 != K2,但f(K1)=f(K2),这种现象称为hash冲突,实际中冲突是不可避免的,只能通过改进哈希函数的性能来减少冲突。
常见处理冲突的方法:
- 开放定址法(再散列法)
- 再哈希法:
- 拉链法(HashMap的冲突处理方式):
- 建立公共溢出区:
哈希表
哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做哈希函数,存放记录的数组称做哈希表。
哈希表是使用 O(1)时间进行数据的插入删除和查找,但是哈希表不保证表中数据的有序性,这样在哈希表中查找最大数据或者最小数据的时间是 O(N) 实现。
面试题一(标准形式)
单词频率:设计一个方法,找出任意指定单词在一本书中的出现频率。
你的实现应该支持如下操作:
- WordsFrequency(book)构造函数,参数为字符串数组构成的一本书
- get(word)查询指定单词在书中出现的频率
代码:
class WordsFrequency {
public:
WordsFrequency(vector<string>& book) {
for (int i = 0; i < book.size(); i++) {
res[book[i]]++;
}
}
int get(string word) {
return res[word];
}
private:
map<string, int> res;
};
/**
* Your WordsFrequency object will be instantiated and called as such:
* WordsFrequency* obj = new WordsFrequency(book);
* int param_1 = obj->get(word);
*/
面试题二
回文排列:给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。
回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。回文串不一定是字典当中的单词。
代码:
class Solution {
public:
/*
回文:
只有一个字母出现奇数次,其他字母全部出现偶数次
全部出现偶数次,则可判定为回文。
*/
bool canPermutePalindrome(string s) {
int hash[128]; //由于ASCII有128个字符
for(int i=0; i<128; i++){//initial
hash[i]=0;
}
//store the appearance time of each letter
for(int i=0; i<s.size(); i++){
hash[s[i]]++;
}
//依次判断是否只出现奇数次或偶数次
int count =0;
for(int i=0; i<128; i++){
if(hash[i]%2==1) count++;
}
if(count ==1 || count ==0){
return true;
}
return false;
}
};
面试题三
变位词组:编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。
代码:
class Solution {
public:
//变位词利用sort后可相同 哈希表添加词下标即可 之后遍历哈希表根据下标添加变位词
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
map<string,vector<int>> map1;
for(int i = 0;i < strs.size();i++) {
string tmp = strs[i];
sort(tmp.begin(),tmp.end());
map1[tmp].push_back(i);
}
//根据关键字输出所有变位词
for(auto m : map1) {
auto t = m.second;
vector<string> words;
for(auto i : t) {
words.push_back(strs[i]);
}
res.push_back(words);
}
return res;
}
};