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

今天做的四道题都和哈希表相关。

思路其实是不难的,但是实际上操作起来的时候会发现stl很多容器用的不熟练,需要增强对set和map的掌握。

242.有效的字母异位词

力扣题目链接:242.有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

示例 1: 输入: s = "anagram", t = "nagaram" 输出: true

示例 2: 输入: s = "rat", t = "car" 输出: false

这道题的思路倒是不复杂,说白了就是判断两个字符串里各字母出现的次数是否相等。

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

此外,学习了后面的题目之后尝试着使用了一下用unordered_map容器来做,也能够顺利实现功能。

class Solution {
public:
	bool isAnagram(string s, string t) {
		unordered_map map;
		for (int i = 0; i < s.length(); i++) {
			auto iter = map.find(s[i]);
			if (iter != map.end()) {
				iter->second++;
			}
			else {
				map.insert(pair(s[i], 1));
			}
		}
		for (int i = 0; i < t.length(); i++) {
			auto iter = map.find(t[i]);
			if (iter == map.end()) return false;
			else {
				if (iter->second == 0) {
					return false;
				}
				else {
					iter->second--;
				}
			}
		}
		for (auto iter = map.begin(); iter != map.end(); ++iter) {
			if (iter->second) {
				return false;
			}
		}
		return true;
	}
};

不过使用这些容器的时候还有一些问题,具体的放在后面的题目细说。

349. 两个数组的交集

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

给定两个数组,编写一个函数来计算它们的交集。

这一题乍一看思路还是比较简单的,使用set容器记录情况就可以了。

但是实际写起代码的时候还是遇到了一些困难。

class Solution {
public:
	vector intersection(vector& nums1, vector& nums2) {
		unordered_set result_set;
		unordered_set nums_set(nums1.begin(), nums1.end());
		for (int num : nums2) {
			if (nums_set.find(num) != nums_set.end()) {
				result_set.insert(num);
			}
		}
		return vector(result_set.begin(), result_set.end());
	}
};
  1. 在构造set的时候没想到可以使用vector的begin和end直接拷贝构造过去。
  2. 在使用for循环的时候不知道可以直接使用num : nums2这种遍历方法。
  3. 对find函数返回值还是不太懂,如果没有找到的话就返回end地址。

202. 快乐数

力扣题目链接:第202题. 快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。

如果 n 是快乐数就返回 True ;不是,则返回 False 。

快乐数重要的是他执行了一系列运算之后是否能化为1,如果不能化为1的话一定会在某一步开始循环。那我们就只需要记录它各个过程化为的数字,如果这个数字在后续重复出现那就说明不是快乐数了。

class Solution {
public:
	bool isHappy(int n) {
		unordered_set result_set;
		int tmp;
		while (true) {
			tmp = 0;
			while (n) {
				tmp += (n % 10) * (n % 10);
				n /= 10;
			}
			if (tmp == 1) return true;
			if (result_set.find(tmp) != result_set.end()) {
				return false;
			}
			result_set.insert(tmp);
			n = tmp;
		}
	}
};

1. 两数之和

力扣题目链接:1. 两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

构建一个哈希表一步步记录nums里各数的值和对应的数组下标,然后寻找看看是否已经记录过target - nums,如果有的话就返回他们的数组下标。

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

可以优化的地方:

  1. 不知道可以使用迭代器。
  2. 不知道可以直接使用return {}返回一个空map
  3. 不知道map中的元素->second对应的就是哈希表记录的内容

你可能感兴趣的:(算法)