2023.1.7 哈希表

一、知识点介绍

二、练习题目

        (1) 1512. 好数对的数目
        (2) 2006. 差的绝对值为 K 的数对数目
        (3) 1347. 制造字母异位词的最小步骤数
        (4) 面试题 10.02. 变位词组

三、算法思路

1. 好数对的数目

        (1) 暴力遍历,符合条件的话,计数器加1
        (2) 最后返回计数器

class Solution {
public:
    int numIdenticalPairs(vector<int>& nums) {
        int cnt = 0;
        for(int i = 0; i < nums.size(); ++i) {
            for(int j = i + 1; j < nums.size(); ++j) {
                if(nums[i] == nums[j]) cnt++;
            }
        }
        return cnt;
    }
};

2. 差的绝对值为 K 的数对数目

        (1) 跟第一道题一样,暴力法

class Solution {
public:
    int countKDifference(vector<int>& nums, int k) {
        int cnt = 0;
        for(int i = 0; i < nums.size(); ++i) {
            for(int j = i + 1; j < nums.size(); ++j) {
                if(abs(nums[i] - nums[j]) == k) cnt++;
            }
        }
        return cnt;
    }
};

3. 制造字母异位词的最小步骤数

        (1) 用两个哈希表分别存下每个字母出现的次数,再做差
        (2) 因为是可以换成任意字母,所以最后结果要除以2。

class Solution {
public:
    int minSteps(string s, string t) {
        int hashs[26];
        int hasht[26];
        int ans = 0;
        memset(hashs, 0, sizeof(hashs));
        memset(hasht, 0, sizeof(hasht));
        for(int i = 0; i < s.size(); ++i) {
            hashs[s[i]-'a']++;
        }
        for(int i = 0; i < t.size(); ++i) {
            hasht[t[i]-'a']++;
        }
        for(int i = 0; i < 26; ++i) {
             ans = ans + abs(hashs[i] - hasht[i]);
        }
        return ans/2;
    }
};

4. 变位词组

        (1) 先用一个二维的哈希表存下每个单词中字母出现的次数
        (2) 再遍历一边,如果两个单词的哈希表一样,说明他们互为变位词组。
        (3) 考虑到会重复遍历,所以再定义一个数组,存下状态(该单词有没有被加入答案数组)。

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> ans;
        int len = strs.size();
        if(len <= 1) return {strs};
        vector<vector<int>> hash(len, vector<int>(26, 0));
        vector<int> visited(len, 0);
        int cnt = 0;
        //每个单词的哈希表
        for(int i = 0; i < len; ++i) {
            for(int j = 0; j < strs[i].size(); ++j) {
                hash[i][strs[i][j] - 'a']++;
            }
        }

        for(int i = 0; i < len; ++i) {
            if(visited[i] == 0) {
                ans.push_back({strs[i]});
                visited[i] = 1;
            }

            for(int j = i + 1; j < len; ++j) {
                if(check(hash[i], hash[j]) && visited[j] == 0) {
                    ans.back().push_back(strs[j]);
                    visited[j] = 1;
                }
            }
            cnt++;
        }
        return ans;
    }
    bool check(vector<int>& str1, vector<int>& str2) {
        for(int i = 0; i < 26; ++i) {
            if(str1[i] != str2[i]) return false;
        }
        return true;

    }
};

四、 总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值