面试题-哈希法及哈希表的应用

哈希法

  哈希法又称散列法、关键字地址计算法等,相应的表成为哈希表。
  哈希法的基本思想:首先在元素的关键字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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值