[前端]_一起刷leetcode 242. 有效的字母异位词

254 阅读2分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

题目:

242. 有效的字母异位词

给定两个字符串 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 仅包含小写字母

 

进阶: 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

思路:

方法1:

  1. 先对字符串进行切割
  2. 然后对切割后的数组进行排序
  3. 最后重新join成字符串
  4. 比较两个字符串是否相等

方法2:

  1. 遍历s中的每个元素,用map记录每个元素出现的次数
  2. 遍历t中的每个元素,从map中取出元素,如果遇到没有的就返回空
  3. 判断map中的元素是否为空

优化:

  1. 前置条件,先判断两个元素是否相等,如果长度不同就不用比较了直接返回false
  2. 把方法2中的第一步和第二步合并,可以达到时间性能最佳

实现:

方法1:

var isAnagram = function(s, t) {
    return s.length == t.length && [...s].sort().join('') === [...t].sort().join('')
};

方法2

/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
  if (s.length !== t.length) {
      return false;
  }

  const n = s.length;

  // 记录各自元素出现的次数。s负责存,t负责取
  let map = new Map();
  for (let i = 0; i < n; i++) {
      map.set(s[i], (map.get(s[i]) || 0) + 1);
      map.set(t[i], (map.get(t[i]) || 0) - 1);
  }

  // 判断是否所有元素刚好为空
  for (let [key, value] of map) {
      if (value !== 0) {
          return false;
      }
  }

  return true;
};

总结:

方法1用了取巧的方法,能够帮助我们快速的解决问题,其中用到的知识点有短路运算符&&和es6的解构...方法,方法2在常规的一轮遍历存数据,一轮遍历取数据的基础上做了优化,用到es6的Map, Map结构的出现可以帮助我们优化很多数组的回显问题,但是在空间性能上带来一定的消耗,也是传统意义上的空间换时间。

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。