代码随想录算法训练营第六天|242.有效的字母异位词 349. 两个数组的交集 202.快乐数 1. 两数之和

目录

哈希结构

LeeCode 242.有效的字母异位词

LeeCode 349. 两个数组的交集

LeeCode 202.快乐数

LeeCode 1. 两数之和

总结 


哈希结构

数组 / set(集合) / map(映射)

set(集合) 的底层实现及优缺点——

集合 底层实现 是否有序 数值是否可以重复 能否更改数值 查询效率 增删效率
std::set 红黑树 有序 O(log n) O(log n)
std::multiset 红黑树 有序 O(logn) O(logn)
std::unordered_set 哈希表 无序 O(1) O(1)

map(映射) 的底层实现及优缺点——

映射 底层实现 是否有序 数值是否可以重复 能否更改数值 查询效率 增删效率
std::map 红黑树 key有序 key不可重复 key不可修改 O(logn) O(logn)
std::multimap 红黑树 key有序 key可重复 key不可修改 O(log n) O(log n)
std::unordered_map 哈希表 key无序 key不可重复 key不可修改 O(1) O(1)

LeeCode 242.有效的字母异位词

力扣题目链接

思路:

定义数组 record 记录字符串 s 中字符出现的次数,将 s 中的字符映射哈希表的数值做 +1 操作,遍历字符串 t ,对t中的字符映射哈希表的数值做 -1 操作,最后遍历数组 record ,若数组元素全为 0 ,则 return true ,反之 return false 。

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

LeeCode 349. 两个数组的交集

力扣题目链接

思路:

将 nums1 数组的元素利用 unordered_set 数据结构进行去重转化后与 nums2 数组元素进行比较,若有相同元素,将其存储在 result_set 中。

class Solution {
public:
    vector intersection(vector& nums1, vector& nums2) {
    	unordered_set result_set;//使用set去重
		unordered_set nums_set(nums1.begin(),nums1.end());
        //对于数组nums2中的每个元素,将其赋值给变量num,然后执行循环中的语句
		for(int num : nums2){
			if(nums_set.find(num) != nums_set.end()){
				result_set.insert(num);
			}
		} 
        return vector(result_set.begin(),result_set.end());
    }
};

因为题目限制了数组的长度,所以可以利用数组做哈希表——

class Solution {
public:
    vector intersection(vector& nums1, vector& nums2) {
    	unordered_set result_set;
		int hash[1001] = {0};
		for(int num : nums1){
			hash[num] = 1; 
		}
		for(int num : nums2){
			if(hash[num] == 1){
				result_set.insert(num);
			}
		}
		return vector(result_set.begin(),result_set.end());
    }
};

LeeCode 202.快乐数

力扣题目链接

思路:

求和的时候若 sum 重复出现,则应 return false , 而判断求和是否重复出现,就需要用到unordered_set。

class Solution {
public:
	//取每个位置上的数字的平方和 
    int getSum(int n){
    	int sum = 0;
    	while(n){
    		sum += (n%10) * (n%10);
    		n /= 10;
		}
    	return sum;
	}
	bool isHappy(int n) {
		unordered_set set;
		while(1){
			int sum = getSum(n);
			if(sum == 1){
				return true;
			}
			if(set.find(sum) != set.end()){
				return false;
			}
			else{
				set.insert(sum);
			}
			n = sum;
		}
    }
};

LeeCode 1. 两数之和

力扣题目链接

思路:

map 用来存放访问过的元素, map 中的存储结构为 { key:数据元素,value:数组元素对应的下标 },在遍历数组时,向 map 去查询是否有和目前遍历元素匹配的数值,若有,则匹配成功;若没有,就把目前遍历的元素放进 map 中。

class Solution {
public:
    vector twoSum(vector& nums, int target) {
    	std::unordered_map  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(nums[i],i));
		}
		return{};
    }
};

总结 

1.需要查询一个元素是否出现过,或者需要快速判断一个元素是否出现集合里的时候,考虑哈希法。

2.如果哈希值比较少、特别分散、跨度非常大,使用数组造成空间浪费。

3.理解思想和写出来能运行通过的代码之间的差距对现在的我来说感觉就像鸿沟,有些语句甚至是之前完全没见过的。

你可能感兴趣的:(LeeCode刷题,算法,leetcode,c++)