题目:(LeetCode 242)给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
思考:
-
首先,应当先确定两个字符串的长度是否相等,如果长度不相等则没有必要继续对比下去,直接返回false
-
其次,分别计算两个字符串中,各单个字符出现的次数,再进行比较,但是在这一步中,首先应当确定两个字符串中都具有相同的字符(这里不知道该如何做到),有一个非常复杂的方法就是创建两个空的数组,存放并记录两个字符串中从a到z字符出现的次数,再把这两个数组进行比较,看是否相等(感觉很累赘,似乎不太可行(再补充:似乎可以))
补充:看了其他人的思路,提到了“哈希”的“代码随想录”,的想法和我的基本相似,不过在数组这一块,他并没有创建两个数组,而是通过嵌套循环,在第二次循环过程中,对第一次记录下来的数据进行一个相减,如果最后这个数组里的数据全都为0的话,那么就证明这两个字符串是有效的字母异位词(👑非常有效的方法,避免了创建第二个数组,减少麻烦)
(📌得到一点小启发:有时候比较两个数组是否相等时,可以通过相减的方法,如果都为0那么就证明他们两个相等)
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function (s, t) {
if (s.length !== t.length) return false;
//如果两个数组的长度不相同,那么也就没有比较的必要
const a = new Array(26).fill(0);
//let arr=new Array(len).fill(init);创建一个指定长度并将数组所有元素初始为init的值
const code = "a".charCodeAt(); //获取“a”ASCII码
//charCodeAt() 是一种字符串方法,用于检索字符串中特定位置的字符的Unicode 值
//语法是:string.charCodeAt([position]);
for (let i = 0; i < s.length; i++) {
a[s[i].charCodeAt() - code]++;
//获取“a”的ASCII码,命名为code
//s[i],是需要验证的字符串,变成数组模式,利用下标i获取每个元素,再利用charCodeAt方法获取这个元素的ASCII码,利用当前元素的ascii码减去字母“a”的ascii码,就是当前元素在字母表中的位置,也即当前元素在这个26个长度数组a中的位置,每检索到一个元素,就为这个元素应当在的位置上加一,统计其出现的次数
}
//接下来再在字符串t中进行检索
for (let i = 0; i < t.length; i++) {
if (!a[t[i].charCodeAt() - code]) return false; //如果a[t[i].charCodeAt() - code]=0,就返回false
//当a[t[i].charCodeAt() - code]=0,也就意味着能够匹配上的字符已经匹配完了,然而,如果出现:下一次循环还是在这个等于0的地方,这种情况时,就意味着两个字符串在这个位置上的字符数量并不相等。
//就算在这一步不直接判断并返回false,那么运行到下一行代码时,进行--操作,就会出现负数,也是不符合条件的
a[t[i].charCodeAt() - code]--; //第一次a[t[i].charCodeAt() - code]等于0的情况,是在这一步完成的,当进入下一次循环,还是在这个等于0的地方时,就返回false
}
/*也可以用for...of来进行遍历循环
for(const i of s) {
resSet[i.charCodeAt() - base]++;
}
for(const i of t) {
if(!resSet[i.charCodeAt() - base]) return false;
resSet[i.charCodeAt() - base]--;
}
*/
return true;
};
console.log(isAnagram("abbbc", "abbcc"));
继续学习🎊