算法训练营第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) {
        mapmap_s;
        mapmap_t;
        for(int i=0;ifirst!=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) {
        vectortable(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 intersection(vector& nums1, vector& nums2) {
        unordered_setans;
        unordered_setnums_set(nums2.begin(),nums2.end());
        for(auto & num:nums1){
            if(nums_set.count(num)){
                ans.insert(num);
            }
        }
        return vector(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_setset;
        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 twoSum(vector& nums, int target) {
        vectorans;
        for(int i=0;i

第二种方法解题思路:

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

代码:

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        unordered_mapmap;
        for(int i=0;isecond,i};
            }
            map.insert(pair(nums[i],i));
        }
        return {};
    }
};

你可能感兴趣的:(算法,散列表,数据结构)