面试算法——哈希表

方法论:

  1. 看题五分钟,不会做,看解析;
  2. 先看中文站,再看国际站;
  3. 选择最优解析;
  4. 回头再来写

面试四步走:

  1. 和面试官,探讨题目限制条件;
  2. 说说可能解,选择最优解;
  3. 码字;
  4. 跑测试用例

242. 有效的字母异位词

可能解:

  1. 排序以后,判断是否相等;
  2. 利用hashmap,统计字符出现个数,然后判断两个hashmap是否相等;
  3. 由于这里字母全是小写,因此,利用数组来统计;
class Solution {
public:
    bool isAnagram(string s, string t) {
        if (s.size() != t.size())
            return false;
       
       int count[26] = {0};
        for (int i = 0; i < s.size(); i++) {
            count[s[i] - 'a']++;
            count[t[i] - 'a']--;
        }
        
       for (int i = 0; i < 26; i++) {
           if (count[i] != 0)
                return false;
       }
       return true;
    }
};

49.字母异位词分组

可能解:

  1. 将数组中, 排序后的字符串作为key,value为一个vector,其中元素为原字符串;
  2. 可以针对排序算法进行优化;
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        unordered_map<string, vector<string>> umap;
        for (string& s : strs){
            string t = s;
            sort(t.begin(), t.end());
            umap[t].push_back(s);
        }

        for (auto u : umap){
            res.push_back(u.second);
        }
        return res;
    }
}

以下代码针对排序算法优化:

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        unordered_map<string, vector<string>> umap;
        for (string& s : strs){ 
            umap[stringstr(s)].push_back(s);
        }
        for (auto u : umap){
            res.push_back(u.second);
        }
        return res;
    }

private:
    string stringstr(string str) {
        int conut[26] = {0};
        for (auto c : str) {
            conut[c - 'a']++;
        } 

        string t;
        for (int i = 0; i < 26; i++) {
            t += string(conut[i], 'a' + i);
        }
        return t;
    }
};

为了便于记忆,这种利用ACSII、26个元素数组的方法,称为 “逐字统计法”;

1. 两数之和

可能解:

  1. Brute暴力法
  2. 两次遍历哈希:第一次,将数组中元素保存为map,其中key为数组元素,value为数组下标;第二次判断 target - a 是否存在map中?
  3. 一次遍历,保存数据的同时,进行判断;
# 1. Brute暴力法
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    	# 边界处理
        for (int i = 0; i < nums.size() - 1; i++) {
            for (int j = i + 1; j < nums.size(); j++) {
                if (nums[i] + nums[j] == target) {
                    return {i, j};
                }
            }
        }
        return {};
    }
};
# 3.一次遍历
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> umap;
        for (int i = 0; i < nums.size(); i++){
            if (umap.find(target - nums[i]) != umap.end()){
                return {i, umap[target - nums[i]]};
            }
             umap[nums[i]] = i;
        }
        return {};
    }
};

总结

  1. 这篇文章需要 注意的是 两数之和的暴力解法中的边界处理、利用ASCII和int count[26]来统计字符出现的个数;

参考

  1. 极客时间-算法训练营-覃超

  2. leetcode中文站

  3. leetcode国际站 (将力扣中文链接,后面的-cn去掉,就是该题的国际站)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值