算法训练营第6天|哈希表 LeetCode242.有效的字母异位词 349.两个数组的交集 202.快乐数 1.两数之和

新的一周,新的开始,今天开始和哈希表相关的内容(ps:算法训练营第5天为休息日)

哈希表理论基础

哈希表,个人理解就是一个带索引的数组,可以通过索引值(key)来找到哈希表中对应的值(value)。

哈希表常用的数据结构有哈希集合(set)和哈希映射(map)。其中哈希集合中有:set(有序,不可重复),multiset(有序,可以重复),unordered_set(无序,不可以重复)。哈希映射中有:map(key有序,key不可重复),multimap(key有序,key可重复),unordered_map(key无序,key不可重复)

哈希表常用函数

判断大小和交换操作

size()//返回容器中元素的数目

empty()//判断容器是否为空

swap()//交换两个集合容器

插入和删除

insert(elem)//在容器中插入元素

clear()//清除所有元素

erase(begin,end)//删除区间中的所有元素,返回下一个元素的迭代器

erase(pos)//删除pos迭代器所指的元素,返回下一个元素的迭代器

erase(key)//删除容器中值为key的元素

查找和统计

find()//查找key是否存在,返回该元素的迭代器,否则返回end()

count()//统计元素个数

LeetCode 242.有效的字母异位词

题目链接:

LeetCode 242.有效的字母异位词

解题思路:

比较直接一点的想法就是,将字符串s和字符串t塞入一个有顺序的哈希表中,之后比较key值个数和每个key值对应的val是否相等,若不相等则返回false

代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        map<char,int>map_s;
        map<char,int>map_t;
        for(int i=0;i<s.size();i++){
            map_s[s[i]]++;
        }
        for(int i=0;i<t.size();i++){
            map_t[t[i]]++;
        }
        for(auto it_s=map_s.begin(),it_t=map_t.begin();it_s!=map_s.end()||it_t!=map_t.end();){
            if(it_s->first!=it_t->first){
                return false;
            }
            if(it_s->second!=it_t->second){
                return false;
            }
            if(it_s!=map_s.end()&&it_t!=map_t.end()){
                it_s++,it_t++;
            }
            else if((it_s==map_s.end()&&it_t!=map_t.end())||(it_s!=map_s.end()&&it_t==map_t.end())){
                return false;
            }
        }
        return true;
    }
};

第二种方法解题思路:

将字符串s中各个字符存在一个数组类的哈希表内,有一个小技巧是减去char类型a的ASCII码,可直接得到字母位置。之后再对字符串t进行变量,减去t中的字符。之后判断vector中所有元素是否全为0,若不为零,则返回false。

代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        vector<int>table(26,0);
        for(auto ch:s){
            table[ch-'a']++;
        }
        for(auto ch:t){
            table[ch-'a']--;
        }
        for(int i = 0;i<26;i++){
            if(table[i]!=0){
                return false;
            }
        }
        return true;
    }
};

LeetCode 349.两个数组的交集

题目链接:LeetCode 349.两个数组的交集

解题思路:

将数组num2塞入哈希集合里,此步同时也去重。之后查找num1中元素是否在哈希集合nums_set中,若再塞入之前建立好的新的哈希集合中,此步为去重操作。之后返回值将该哈希集合转化为数组。

代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int>ans;
        unordered_set<int>nums_set(nums2.begin(),nums2.end());
        for(auto & num:nums1){
            if(nums_set.count(num)){
                ans.insert(num);
            }
        }
        return vector<int>(ans.begin(),ans.end());
    }
};

LeetCode 202.快乐数

题目链接:LeetCode 202.快乐数

解题思路:

先建立一个单独的函数,来计算数字的各个位的平方和,之后主函数建立一个一个哈希集合用来判断是否计算数字结果重复,是否进如循环,如何进入循环则返回false,否则持续计算直到n==1,跳出返回true。

代码:

class Solution {
public:
    int calculate(int n){
        //计算各位数的平方和
        int sum = 0;
        while(n!=0){
            int num = n%10;
            n = n/10;
            sum += num*num;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int>set;
        while(n!=1){
            n = calculate(n);
            if(set.count(n)){
                return false;
                break;
            }
            set.insert(n);
        }
        return true;
    }
};

LeetCode 1.两数之和

题目链接:LeetCode 1.两数之和

解题思路:

暴力法,直接一个双层循环,之后把符合位置的坐标放入数组中。

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

第二种方法解题思路:

满足题目进阶要求,降低时间复杂度。通过简历哈希表的方式进行查找是否有符合索引的下标,因为哈希表的索引时间复杂度为O(1)。在变量过程中,如果有符合的下标对,则直接返回。如何没有,则将{nums[i],i}插入到哈希表中。

代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int>map;
        for(int i=0;i<nums.size();i++){
            auto iter = map.find(target-nums[i]);
            if(iter!=map.end()){
                return {iter->second,i};
            }
            map.insert(pair<int,int>(nums[i],i));
        }
        return {};
    }
};

  • 43
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值