「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。
前言
大家好,我是程序猿小白 GW_gw,很高兴能和大家一起学习进步。
以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。
摘要
本文主要介绍LeetCode题目 有效的字母异位词 的一些解法和思路。
【题目】
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
提示:
1 <= s.length, t.length <= 5 * 104 s 和 t 仅包含小写字母
题目链接:leetcode-cn.com/leetbook/re…
【解法一】
【思路】
使用两个数组存储两个字符串每个字母出现的次数,依次进行比较。
- 确定特殊情况,如果长度不相同肯定不符合。
- 循环两个字符串,依次记录字符出现的次数。
- 循环对比两个数组。
【代码】
public static boolean isAnagram(String s, String t) {
/*
解法1:使用两个数组存储两个字符串每个字母出现的次数,依次进行比较。
*/
//先判断两个字符串长度是否相等
if (s.length() != t.length()) {
return false;
}
int[] s1 = new int[26];
int[] t1 = new int[26];
int index = 0;
for (int i = 0; i < s.length(); i++) {
index = s.charAt(i) - 'a';
s1[index] += 1;
}
for (int i = 0; i < t.length(); i++) {
index = t.charAt(i) - 'a';
t1[index] += 1;
}
for (int i = 0; i < 26; i++) {
if (s1[i] != t1[i]) {
return false;
}
}
return true;
}
【解法二】
【思路】
利用map,存储两个字符串中每个字母出现的次数。
和第一种解法思想一致,只不过一个使用了数组,一个使用了map集合。 【代码】
public static boolean isAnagram(String s, String t) {
/*
解法2:利用map,存储两个字符串中每个字母出现的次数。
*/
//先判断两个字符串长度是否相等
if (s.length() != t.length()) {
return false;
}
Map<Character, Integer> map1 = new HashMap<>();
Map<Character, Integer> map2 = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
map1.put(c, map1.getOrDefault(c, 0) + 1);
}
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
map2.put(c, map2.getOrDefault(c, 0) + 1);
}
for (Character c : map1.keySet()) {
if (map2.get(c) == null || !map1.get(c).equals(map2.get(c))) {
return false;
}
}
return true;
}
【解法三】
【思路】
使用数组记录第一个字符串各个字符出现的次数,然后和第二个字符依次比较,如果有该字符串就减1,抵消掉一个。如果没有则直接返回false即可,最后也要对数组进行判断,看是否最后刚好抵消。
【代码】
public static boolean isAnagram(String s, String t) {
/*
解法3:计算两个字符串字符的差值
*/
//先判断两个字符串长度是否相等
if (s.length() != t.length()) {
return false;
}
int[] count = new int[26];
int index = 0;
for (int i = 0; i < s.length(); i++) {
index = s.charAt(i) - 'a';
count[index] += 1;
}
for (int i = 0; i < t.length(); i++) {
index = t.charAt(i) - 'a';
//如果等于0,则说明另一个字符串没有该字符,如果不为0,则减一
if (count[index] == 0) {
return false;
} else {
count[index]--;
}
}
for (int i = 0; i < 26; i++) {
if (count[i] != 0) {
return false;
}
}
return true;
}
【解法四】
【思路】
先排序再比较
- 把字符串转化为数组
- 对数组排序
- 直接比较,如果是则排序之后完全相同。
【代码】
public static boolean isAnagram(String s, String t) {
/*
解法4:先排序再比较
*/
//先判断两个字符串长度是否相等
if (s.length() != t.length()) {
return false;
}
char[] s1 = s.toCharArray();
char[] t1 = t.toCharArray();
Arrays.sort(s1);
Arrays.sort(t1);
return Arrays.equals(s1, t1);
}
【解法五】
【思路】
字符抵消法。
- 建立长度为26的数组,记录各个字符出现的次数。字符串s和字符串t共用一个数组来记录,如果s中存在就加1,t中存在就减1.
- 创建计数器count,统计两个字符串不相同的字符个数。如果最后为0则满足题意,否则不满足。
- 循环比较,判断该字符出现的次数,对应位置等于1说明在s中有,t中没有。
- 最后判断count即可。
【代码】
public static boolean isAnagram(String s, String t){
/*
解法5:字符抵消法。
*/
//先判断两个字符串长度是否相等
if (s.length() != t.length()) {
return false;
}
//记录各个符出现的次数
int[] n = new int[26];
//记录两个字符串中不同字符的种类的数量。如果最后为0,说明两个字符串满足条件
int count=0;
for (int i = 0; i < s.length(); i++) {
//对应位置等于1,说明出现了新字符
if(++n[s.charAt(i)-'a']==1){
count++;
}
//等于0,说明没有该字符了
if(--n[t.charAt(i)-'a']==0){
count--;
}
}
return count==0;
}
小结
以上就是该题的五种解法,希望能对读者有所帮助,如有不正之处,欢迎留言指正。