开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 14 天,点击查看活动详情
题目描述:
给定两个字符串
s和t,编写一个函数来判断t是否是s的字母异位词。注意: 若
s和t**中每个字符出现的次数都相同,则称s和t**互为字母异位词。
在前文中提及了哈希表相关的概念,正是这道算法题的一种比较好的解法。
在前端中,数组可以理解成是一个哈希结构,Object、Set、WeakSet、Map、WeakMap 等也都属于是哈希结构,使用哈希表来进行查找速度更快。
实现方案
第一种 暴力法
提到暴力法不得不说的就是它的时间复杂度了,双层 for 循环进行遍历,同时记录字符重复出现的次数。
时间复杂度为 O(n^2)。
第二种 哈希表
这道题目主要来说一说哈希表的实现思路:
- 首先判断两个字符串的长度是否相同,如果不相同就一定不是异位词,返回 false
- 定义一个数组,默认值为 0
- 以字符 'a' 的 Unicode 编码作为一个基准,用当前字符的值减去 'a' 的 Unicode 编码,得到的差值作为数组的下标,这样从 a-z 的26个英文字母的下标就是 0-25
- 遍历第一个字符串,第一个串中字符的计数每次 +1
- 遍历第二个字符串,如果在这个循环中当前字符的计数为 0,说明不是异位词(因为减 1 之后会变成 -1),第二个串中字符的计数每次 -1
- 循环完毕,最后返回 true
时间复杂度:O(n),代码如下:
var isAnagram = function(s, t) {
if(s.length !== t.length) return false;
const arr = new Array(30).fill(0);
const base = 'a'.charCodeAt();
for(const i of s) {
arr[i.charCodeAt() - base]++;
}
for(const i of t) {
if(!arr[i.charCodeAt() - base]) return false;
arr[i.charCodeAt() - base]--;
}
return true;
};
第三种 排序法
排序法相对来说比较巧妙,代码量比较少,但是时间复杂度上还是哈希表更低一些。
思路就是就是将两个字符串中的元素按照字母顺序排列,再进行对比,如果有不同的字母,则不是异位词。
时间复杂度:O(nlogn)。
var isAnagram = function(s, t) {
return s.length == t.length && [...s].sort().join('') === [...t].sort().join('')
}
用到的相关方法
- charCodeAt
charCodeAt() 方法可返回指定位置的字符的 Unicode 编码,返回值是 0 - 65535 之间的整数,表示给定索引处的 UTF-16 代码单元
var str = "apple";
var n = str.charCodeAt(0);
console.log(n)
等同于:
'a'.charCodeAt()
运行结果: 97