您现在的位置是:首页 >其他 >代码随想录算法训练营第六天|242.有效的字母异位词 349. 两个数组的交集 202.快乐数 1. 两数之和网站首页其他

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

禹泽. 2023-06-11 16:00:02
简介代码随想录算法训练营第六天|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<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    	unordered_set<int> result_set;//使用set去重
		unordered_set<int> 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<int>(result_set.begin(),result_set.end());
    }
};

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

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    	unordered_set<int> 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<int>(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<int> 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<int> twoSum(vector<int>& nums, int target) {
    	std::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{};
    }
};

总结 

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

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

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

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。