题目:给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的 字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram" 输出: true
示例 2:
输入: s = "rat", t = "car" 输出: false
第一种解题思路+代码:
代码:
class Solution {
public boolean isAnagram(String s, String t) {
//拿到题我最先想到的思路是将字符串转化成ASCII码进行匹配,数值匹配成功即返回true,否则返回false(计数-->转化成ASCII码)
/*
1.首先判断两个字符串的长度是否相等,如果不相等直接返回false
2.相等再做字符计数操作,计数相符返回true,否则返回false
*/
//1.先判断两个字符串的长度是否相等,如果不相等直接返回false
if(s.length() != t.length()){
return false;
}
//创建两个数组,用来记录字符出现的次数
int[] countS = new int[128];
int[] countT = new int[128];
//遍历两个字符串,记录字符出现的次数
for(int i = 0;i<s.length();i++){
countS[s.charAt(i)]++;
}
for(int i = 0;i<t.length();i++){
countT[t.charAt(i)]++;
}
//遍历字符串 s 和 t,将每个字符的 ASCII 码作为索引,增加对应数组中的计数。最后比较两个数组的计数是否相等
for(int i = 0;i<128;i++){
if(countS[i] != countT[i]){
return false;
}
}
return true;
}
}
代码优化思路:
空间优化:只使用一个数组来记录字符出现次数。遍历字符串 s
时增加计数,遍历字符串 t
时减少计数。最后检查数组中所有元素是否都为 0。
时间优化:如果字符串只包含小写字母,可以将数组长度从 128 减少到 26,以节省空间和时间。
代码优化实现:
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}
int[] count = new int[26]; // 假设只包含小写字母
for (int i = 0; i < s.length(); i++) {
count[s.charAt(i) - 'a']++;
count[t.charAt(i) - 'a']--;
}
for (int i = 0; i < 26; i++) {
if (count[i] != 0) {
return false;
}
}
return true;
}
}
这种方法的时间复杂度为 O(n),其中 n 是字符串的长度,空间复杂度为 O(1)(假设字符集大小是常数)。
第二种解题思路+代码:(在看评论区其他解法时看到的使用哈希表解题:引用评论区--作者:Krahets 题解:https://leetcode.cn/problems/valid-anagram/solutions/2362065/242-you-xiao-de-zi-mu-yi-wei-ci-ha-xi-bi-cch7/)
代码:
class Solution {
public boolean isAnagram(String s, String t) {
//使用哈希表
// 获取两个字符串的长度
int len1 = s.length(), len2 = t.length();
// 如果两个字符串长度不同,直接返回 false
if (len1 != len2)
return false;
// 创建一个 HashMap 来记录字符及其出现次数
HashMap<Character, Integer> dic = new HashMap<>();
// 遍历字符串 s,记录每个字符的出现次数
for (int i = 0; i < len1; i++) {
// 使用 getOrDefault 方法,如果字符不存在则默认为 0,然后加 1
dic.put(s.charAt(i), dic.getOrDefault(s.charAt(i), 0) + 1);
}
// 遍历字符串 t,减少每个字符的出现次数
for (int i = 0; i < len2; i++) {
// 使用 getOrDefault 方法,如果字符不存在则默认为 0,然后减 1
dic.put(t.charAt(i), dic.getOrDefault(t.charAt(i), 0) - 1);
}
// 遍历 HashMap 中的所有值
for (int val : dic.values()) {
// 如果某个字符的出现次数不为 0,说明两个字符串不是字母异位词
if (val != 0)
return false;
}
// 如果所有字符的出现次数都为 0,说明两个字符串是字母异位词
return true;
}
}
这种方法和上面第一种方法的时间复杂度为 O(n),空间复杂度为 O(1) 是一样(假设字符集大小是常数)。
总结:个人认为解出此题并不难,重要的是解题思路。我们解答任何一道算法题都是要先理清解题的思路,再将思路一步步用代码实现。继续加油~~