242. 有效的字母异位词
题目中关于 “异位词” 的定义:两字符串中每个字符出现的次数都相同,则两个字符串互称为异位词。
得到重要信息,字符串长度相等,并且出现的字符种类和数量也相等。因此可以使用哈希表存储一个字符串中每个字符出现的数量,然后再遍历另一个字符串,将出现在哈希表中的字符的数量 -1,如果最后哈希表中各个字符的数量都为 0,说明两个字符串出现的字符的种类和数量相等。
因为 s、t 都是小写字母,因此可以用长度为 26 的数组作为哈希表。
class Solution {
public boolean isAnagram(String s, String t) {
// 长度不相等,不是异位词
if (s.length() != t.length()) return false;
// 哈希表
int[] records = new int[26];
// 统计 s 中各字符出现的次数
for (char c: s.toCharArray()) {
records[c - 'a']++;
}
// 遍历 t,削减哈希表中该字符的数量
for (char c: t.toCharArray()) {
records[c - 'a']--;
// 如果数量变为了负数,说明 s 中 c 字符的数量不够,所以不是异位词
if (records[c - 'a'] < 0) return false;
}
// 如果还有某些字符的数量大于零,说明 s 中某个字符的数量大于 t,因此不是异位词
for (int i: records) {
if (records[i] > 0) return false;
}
return true;
}
}
349. 两个数组的交集
交集就是查看一个集合中的哪些元素在另一个集合中。因此可以先用哈希表存储一个集合中的元素,然后再遍历另一个集合,把相同的元素存起来,存起来的元素可以用哈希表去重。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> nums1Set = new HashSet<>();
Set<Integer> resSet = new HashSet<>();
// 先存储 nums1 中出现的数字
for (int num: nums1) {
nums1Set.add(num);
}
// 再遍历 nums2,看看 nums1Set 中是否存在,存在就是相交的元素,存起来
for (int num: nums2) {
if (nums1Set.contains(num)) {
resSet.add(num);
}
}
// 整理结果集,转为数组
int[] res = new int[resSet.size()];
int i = 0;
for (int num: resSet) {
res[i++] = num;
}
return res;
}
题目中,nums[i] 的范围在 0 ~ 1000,因此哈希表也可以采用长度为 1000 的数组,数组值就是 0 和 1,0 表示集合中没出现这个数字,反之则出现过。
202. 快乐数
n 的范围是 1 ~ 2^31-1,最多十位数,如果每位数字都是 9(虽然 10 个 9 已经超出范围了),平方和也才是 810,也就是说对 n 求出的各位数字的平方和的范围可以 简单理解为 1 ~ 810。所以平方和是有界的,无限循环一定是某些 sum 重复了,sum 不会是无限循环不重复的值。因此可以使用哈希表存储 sum,如果再次出现,说明会无限循环,不是快乐数,当然也可以使用一个长度为 810 的数组当作哈希表。
class Solution {
public boolean isHappy(int n) {
// 存放已求出的和
Set<Integer> set = new HashSet<>();
// int[] set = new int[810];
while(true) {
// 计算各位的平方和
int sum = getSum(n);
// 1,是快乐数
if (sum == 1) return true;
// sum 出现过,会无限循环
if (set.contains(sum)) return false;
// if (set[sum] == 1) return false;
// 存起来,继续求和
set.add(sum);
// set[sum] = 1;
n = sum;
}
}
// 求各位的平方和
public int getSum(int n) {
int sum = 0;
while (n > 0) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
}
1. 两数之和
使用哈希表,然后遍历数组,去哈希表里面查找差值,如果差值在哈希表里面,则找到一个解。
class Solution {
public int[] twoSum(int[] nums, int target) {
// 存储遍历过的值
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 去哈希表中看看有没有值和当前值加起来等于目标值
if (map.containsKey(target - nums[i])) {
// 有,则返回两个值的下标
return new int[]{i, map.get(target - nums[i])};
} else {
// 否则将当前值及其下标放进哈希表
map.put(nums[i], i);
}
}
// 没找到
return new int[]{-1, -1};
}