仅含有小写字母的哈希题
仅含有小写字母的哈希题时,可以采用数组的hash表结构
- 有效字母的异位词
class Solution {
public boolean isAnagram(String s, String t) {
int[] hash = new int[26];
for (int i = 0; i < t.length(); i++) {
hash[t.charAt(i) - 'a']++;
}
for (int j = 0; j < s.length(); j++) {
hash[s.charAt(j) - 'a']--;
}
for (int k = 0; k < 26; k++) {
if (hash[k] != 0) {
return false;
}
}
return true;
}
}
仅判断元素是否出现的哈希题
题中只要判断某个元素是否要出现的情况使用HashSet
- 两个数组的交集
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> hashset1 = new HashSet<>();
Set<Integer> hashset2 = new HashSet<>();
List<Integer> res = new ArrayList<>();
for (Integer i : nums1) {
hashset1.add(i);
}
for (Integer j : nums2) {
hashset2.add(j);
}
for (Integer k : hashset1) {
if (hashset2.contains(k)) {
res.add(k);
}
}
int[] ans = new int[res.size()];
int index = 0;
for (Integer i : res) {
ans[index++] = i;
}
return ans;
}
}
- 快乐数
按照题中的算法:
1)出现重复的结果无限循环
2)结果为1
所以用hashset
class Solution {
public boolean isHappy(int n) {
Set<Integer> hashset = new HashSet<>();
while (true) {
int sum = getSum(n);
if (sum == 1) {
return true;
}
if (hashset.contains(sum)) {
return false;
} else {
hashset.add(sum);
}
n = sum;
}
}
int getSum(int n) {
int sum = 0;
while (n > 0) {
sum += (n % 10) * (n % 10);
n = n / 10;
}
return sum;
}
}
元素具有关联数据或者统计性的hash题
当元素需要额外的数据或者需要对元素进行统计的时候用hashmap
- 两数之和
两数之和的本质就是判断当前列表是否有(target - 当前元素)。
两数之和不能用双指针做法,因为双指针方法需要数组有序。而两数之和要求返回索引,并且给出的数组无序(如果改为存在就可以用双指针,同时也可以用hash表,退化为hashset)。
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if (nums == null || nums.length == 0) {
return res;
}
HashMap<Integer, Integer> hashmap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
if (hashmap.containsKey(temp)) {
res[1] = i;
res[0] = hashmap.get(temp);
}
hashmap.put(nums[i], i);
}
return res;
}
}
- 四数之和(四个数组)
如果是一个数组中的三数之和 和 四数之和用双指针更好
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
HashMap<Integer, Integer> hashmap = new HashMap<>();
for (Integer a : nums1) {
for (Integer b : nums2) {
hashmap.put(a + b,
hashmap.getOrDefault(a + b, 0) + 1);
}
}
int count = 0;
for (Integer c : nums3) {
for (Integer d : nums4) {
if (hashmap.containsKey(0 - c - d)) {
count += hashmap.get(0 - c - d);
}
}
}
return count;
}
}
- 赎金信
赎金信的解法可以用于 76题 覆盖最小子串 ,该题中的check函数可以使用这个方法。
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] hashset = new int[26];
for (int i = 0; i < magazine.length(); i++) {
hashset[magazine.charAt(i) - 'a']++;
}
for (int j = 0; j < ransomNote.length(); j++) {
hashset[ransomNote.charAt(j) - 'a']--;
}
for (Integer i : hashset) {
if (i < 0) {
return false;
}
}
return true;
}
}