算法-哈希表

一、知识点介绍

哈希表

1. 介绍

unordered_map是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能

2. 特性
  • 关联性:通过key去检索value,而不是通过绝对地址(和顺序容器不同)
  • 无序性:使用hash表存储,内部无序
  • Map : 每个值对应一个键值
  • 键唯一性:不存在两个元素的键一样
  • 动态内存管理:使用内存管理模型来动态管理所需要的内存空间

3. 迭代器
  • unordered_map的迭代器是一个指针,指向这个元素,通过迭代器来取得它的值。
1 unordered_map<Key,T>::iterator it;
2 (*it).first;             // the key value (of type Key)
3 (*it).second;            // the mapped value (of type T)
4 (*it);                   // the "element value" (of type pair<const Key,T>) 
  • 它的键值分别是迭代器的first和second属性。
1 it->first;               // same as (*it).first   (the key value)
2 it->second;              // same as (*it).second  (the mapped value) 

二、练习题目

        (1) 442. 数组中重复的数据
        (2) 2068. 检查两个字符串是否几乎相等
        (3) 2283. 判断一个数的数字计数是否等于数位的值
        (4) 884. 两句话中的不常见单词

三、算法思路

1. 数组中重复的数据

        (1) 用一个哈希表存入每个数字出现的次数;
        (2)再遍历哈希表,出现两次的元素存入答案数组并返回。

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        int hash[100010];
        memset(hash, 0, sizeof(hash));
        int i;
        vector<int> ans;
        for(i = 0; i < nums.size(); ++i) {
            ++hash[nums[i]];
        }
        for(i = 0; i < 100010; ++i) {
            if(hash[i] == 2) {
                ans.push_back(i);
            }
        }
        return ans;

    }
};

2. 检查两个字符串是否几乎相等

        (1) 用两个哈希表存入每个字符串字母出现的次数;
        (2)再判断这两个哈希表是否相同;相同就返回true,否则就返回false。

class Solution {
    int code(char c) {
        return c - 'a';
    }
public:
    bool checkAlmostEquivalent(string word1, string word2) {
        bool ans = false;
        int hash1[26];
        int hash2[26];
        memset(hash1, 0, sizeof(hash1));
        memset(hash2, 0, sizeof(hash2));
        int i;
        for(i = 0; i < word1.size(); ++i) {
            ++hash1[code(word1[i])];
        }
        for(i = 0; i < word2.size(); ++i) {
            ++hash2[code(word2[i])];
        }
        for(i = 0; i < 26; ++i) {
            if(abs(hash1[i]-hash2[i]) <= 3) ans = true;
            else {
                ans = false;
                break;
            }
        }
        return ans;
    }
};

3. 判断一个数的数字计数是否等于数位的值

        (1) 首先需要写一个方法把字符串转换成数字。
        (2) 再把每一次数字出现的次数存入一个哈希表中;
        (3) 再按照题意判断哈希表中对应的次数和数字是否相等,如果相等返回true;否则返回false。

class Solution {
    int code(char c) {
        return c - '0';
    }
public:
    bool digitCount(string num) {
        int hash[10];
        memset(hash, 0, sizeof(hash));
        bool ans;
        int i;
        for(i = 0; i < num.size(); ++i) {
            ++hash[code(num[i])];
        }
        for(i = 0; i < num.size(); ++i) {
            if(code(num[i]) == hash[i]) ans = true;
            else {
                ans = false;
                break;
            }
        }
        return ans;
    }
};

4. 两句话中的不常见单词

        (1) 首先先拼接两个字符串;
        (2) 再通过空格判断每个单词,并把每个单词存入哈希map中,统计出现的次数;
        (3) 如果只出现一次的话,就存入答案数组中并返回。

class Solution {
    unordered_map<string, int> hash;
public:
    vector<string> uncommonFromSentences(string s1, string s2) {
        s1 += " ";
        s1 += s2;
        s1 += " ";
        int i;
        char temp[420];
        int size = 0;
        vector<string> ans;
        for(i = 0; i < s1.size(); ++i) {
            if(s1[i] == ' ') {
                temp[size] = '\0';
                if(size) {
                    hash[temp]++;
                }
                size = 0;

            } else {
                temp[size++] = s1[i];
            }
        }
        for(auto iter = hash.begin(); iter != hash.end(); ++iter) {
            if(hash[iter->first] == 1) {
                ans.push_back(iter->first);
            }
        }
        return ans;
    }
};

四、 总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值