java
复制代码
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
// 创建一个 HashMap 来存储 magazine 中字符出现的次数
Map<Character, Integer> map = new HashMap<>();
// 遍历 magazine 字符串,将每个字符及其出现的次数存入 map 中
for (char c : magazine.toCharArray()) {
// 如果字符 c 已经在 map 中,将其对应的值加 1
// 如果字符 c 不在 map 中,将其添加到 map 中并初始化为 0 ,然后加 1
map.put(c, map.getOrDefault(c, 0) + 1);
}
// 遍历 ransomNote 字符串
for (char r : ransomNote.toCharArray()) {
// 如果 map 中字符 c 的出现次数为 0 ,说明无法构建 ransomNote ,返回 false
if (map.getOrDefault(r, 0) == 0) {
return false;
}
// 如果字符 c 的出现次数不为 0 ,则将其对应的值减 1
map.put(r, map.getOrDefault(r, 0) - 1);
}
// 如果遍历完 ransomNote 都没有出现无法构建的情况,返回 true
return true;
}
}
java
复制代码
class Solution {
public boolean isIsomorphic(String s, String t) {
// 创建两个哈希表,分别用于存储 s 到 t 和 t 到 s 的映射
Map<Character, Character> s2t = new HashMap<>();
Map<Character, Character> t2s = new HashMap<>();
// 获取字符串的长度
int len = s.length();
// 遍历每个字符
for (int i = 0; i < len; i++) {
// 获取 s 和 t 中对应位置的字符
char x = s.charAt(i);
char y = t.charAt(i);
// 检查当前字符 x 是否已经在 s2t 中映射到一个不同的字符 y
// 同时检查字符 y 是否已经在 t2s 中映射到一个不同的字符 x
if ((s2t.containsKey(x) && s2t.get(x) != y) || (t2s.containsKey(y) && t2s.get(y) != x)) {
// 如果发现不一致,返回 false
return false;
}
// 如果没有冲突,更新映射
// x 映射到 y
s2t.put(x, y);
// y 映射到 x
t2s.put(y, x);
}
// 如果遍历完都没有冲突,返回 true
return true;
}
}
java
复制代码
class Solution {
public boolean wordPattern(String pattern, String s) {
// pattern = "abba", s = "dog cat cat dog" true
// 输入的模式是 "abba",字符串是 "dog cat cat dog",返回 true
// 将字符串 s 按空格分割成数组
String[] arr = s.split(" ");
// 如果模式长度与分割后的数组长度不相等,返回 false
if (pattern.length() != arr.length) {
return false;
}
// 创建两个映射,用于模式到字符串和字符串到模式的映射
Map<Character, String> p2s = new HashMap<>();
Map<String, Character> s2p = new HashMap<>();
// 遍历模式和对应的字符串
for (int i = 0; i < arr.length; i++) {
// 获取当前模式字符
char p = pattern.charAt(i);
// 获取当前分割后的字符串
String str = arr[i];
// 检查模式字符和字符串的映射是否一致
// 如果模式字符已经存在于 p2s 映射中且对应的字符串不匹配,返回 false
// 如果字符串已经存在于 s2p 映射中且对应的模式字符不匹配,返回 false
if ((p2s.containsKey(p) && !p2s.get(p).equals(str)) || (s2p.containsKey(str) && !s2p.get(str).equals(p))) {
return false;
}
// 建立新的映射关系
// 将模式字符映射到字符串
p2s.put(p, str);
// 将字符串映射到模式字符
s2p.put(str, p);
}
// 如果遍历完所有字符都没有不匹配的情况,返回 true
return true;
}
}
java
复制代码
class Solution {
// 定义一个方法来判断两个字符串是否为字母异位词(即包含相同字符,但顺序不同)
public boolean isAnagram(String s, String t) {
// s = "anagram", t = "nagaram" true
// 如果两个字符串的长度不同,直接返回 false
if (s.length() != t.length()) {
return false;
}
// 使用 HashMap 来存储字符及其出现次数
Map<Character, Integer> map = new HashMap<>();
// 遍历字符串 s,记录每个字符的出现次数
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 更新 HashMap 中该字符的计数
map.put(c, map.getOrDefault(c, 0) + 1);
}
// 遍历字符串 t,减少对应字符的出现次数
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
// 在 HashMap 中将该字符的计数减一
map.put(c, map.getOrDefault(c, 0) - 1);
// 如果某个字符的计数小于零,说明 t 中的该字符超过了 s 中的数量,返回 false
if (map.get(c) < 0) {
return false;
}
}
// 如果所有字符的计数都正确,返回 true,表示 s 和 t 为字母异位词
return true;
}
}
java
复制代码
class Solution {
// 方法 groupAnagrams 接收一个字符串数组 strs,返回字谜的分组列表
public List<List<String>> groupAnagrams(String[] strs) {
// 创建一个 Maps,用于将排序后的字符串作为关键字,与列表关联
Map<String, List<String>> map = new HashMap<>();
// 遍历字符串数组中的每个字符串
for (String str : strs) {
// 将字符串转换为字符数组
char[] arr = str.toCharArray();
// 对字符数组进行排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// 将排序后的字符数组重新转换为字符串作为键
String key = new String(arr);
System.out.println(key);
// 根据键从 map 中获取对应的字谜列表,如果不存在则初始化一个新的列表
List<String> list = map.getOrDefault(key, new ArrayList<>());
// 将当前字符串加入到对应的字列表中
list.add(str);
// 将更新后的列表放回 map 中
map.put(key, list);
}
// 返回 map 中所有值的列表,转换为 List<List<String>> 类型
return new ArrayList<>(map.values());
}
}
java
复制代码
class Solution {
/**
* 两数之和
* @nums 整数数组
* @target 目标值
*/
public int[] twoSum(int[] nums, int target) {
// 创建一个用于存储数字及其索引的 HashMap
Map<Integer, Integer> map = new HashMap<>();
// 遍历数组
for (int i = 0; i < nums.length; i++) {
// 如果 HashMap 中包含目标值减去当前数字的差值
if (map.containsKey(target - nums[i])) {
// 返回当前索引和差值对应的索引
return new int[]{i, map.get(target - nums[i])};
}
// 将当前数字及其索引存入 HashMap
map.put(nums[i], i);
}
// 如果遍历完数组都未找到,返回空数组
return new int[0];
}
}
java
复制代码
class Solution {
/**
* 判断一个整数是否为快乐数
* @param n 待判断的整数
* @return 如果是快乐数返回 true,否则返回 false
*/
public boolean isHappy(int n) {
// 创建一个 HashSet 用于存储出现过的数字
Set<Integer> set = new HashSet<>();
// 当 n 不等于 1 且 n 未曾出现过时,执行循环
// (为什么要判断是否在集合内,因为在集合内,就会陷入无限循环)
while(n != 1 && !set.contains(n)) {
// 将当前 n 加入 HashSet 中
set.add(n);
// 计算 n 的下一个数字
n = getNext(n);
}
// 返回 n 是否等于 1
return n == 1;
}
/**
* 计算给定整数的下一个数字
* @param n 输入的整数
* @return 计算得到的下一个数字
*/
private int getNext(int n) {
int sum = 0;
int cur = 0;
// 当 n 大于 0 时
while(n > 0) {
// 获取 n 的最后一位数字
cur = n % 10;
// 去掉 n 的最后一位数字
n = n / 10;
// 计算当前数字的平方并累加到 sum 中
sum = sum + cur * cur;
}
// 返回计算得到的下一个数字
return sum;
}
}
java
复制代码
class Solution {
/**
* 检查给定整数数组中是否存在两个相同元素,其索引之差不超过给定值 k
*
* @param nums 整数数组
* @param k 最大索引差
* @return 如果存在这样的重复元素返回 true,否则返回 false
*/
public boolean containsNearbyDuplicate(int[] nums, int k) {
// 创建一个 HashMap 用于存储元素及其对应的索引
Map<Integer, Integer> map = new HashMap<>();
// 遍历数组
for (int i = 0; i < nums.length; i++) {
int num = nums[i];
// 如果 HashMap 中已包含当前元素,并且当前索引与之前存储的索引之差小于等于 k
if (map.containsKey(num) && i - map.get(num) <= k) {
return true;
}
// 将当前元素及其索引存入 HashMap
map.put(num, i);
}
// 如果遍历完都未找到满足条件的重复元素,返回 false
return false;
}
}
java
复制代码
class Solution {
public int longestConsecutive(int[] nums) {
// 创建一个 HashSet 用于存储数组中的元素,以便快速查找元素是否存在
Set<Integer> num_set = new HashSet<Integer>();
for (int num : nums) {
num_set.add(num);
}
// 用于记录最长连续序列的长度
int longestStreak = 0;
for (int num : num_set) {
// 如果当前数字的前一个数字不存在,说明当前数字可能是一个连续序列的起始数字
if (!num_set.contains(num - 1)) {
int currentNum = num;
// 记录当前连续序列的长度,初始为 1
int currentStreak = 1;
// 当当前数字的下一个数字存在于集合中时,继续增加当前连续序列的长度
while (num_set.contains(currentNum + 1)) {
currentNum += 1;
currentStreak += 1;
}
// 更新最长连续序列的长度
longestStreak = Math.max(longestStreak, currentStreak);
}
}
return longestStreak;
}
}