代码随想录算法训练营第六天|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.理解思想和写出来能运行通过的代码之间的差距对现在的我来说感觉就像鸿沟,有些语句甚至是之前完全没见过的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值