LeetCode探索(17):242-有效的字母异位词

680 阅读2分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

题目

给定两个字符串 st ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:st 中每个字符出现的次数都相同,则称 st 互为字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true

示例 2:

输入: s = "rat", t = "car"
输出: false

提示:

  • 1 <= s.length, t.length <= 5 * 10^4
  • st 仅包含小写字母

进阶: 如果输入字符串包含 unicode 字符怎么办?

思考

这是字符串相关的一道题,难度简单~

题目中定义字符串st 互为字母异位词的条件是,st 中每个字符出现的次数都相同 。那么,当两个字符串的长度不一致时,一定不满足互为字母异位词。同时,我们可以通过统计每个字符的数量,来解决这个问题。

如何对字符串中的每个字符进行计数呢?我们可以定义数组长度为26的数组arr,因为st 仅包含小写字母。数组的索引对应的是字符a, b, c等。通过s.charCodeAt(i) - 'a'.charCodeAt(),取出字符串s的字符与字符a进行比较,对于字符 a,对应的是索引0,字符 b 对应索引1,依此类推。

我们将字符串中字符出现的次数设置为0,最终,当某个字符出现的次数为负数时,不满足互为字母异位词。

解答

方法一:字符计数

var isAnagram = function(s, t) {
  if (s.length !== t.length) { // 长度比较
    return false
  }
  let arr = new Array(26).fill(0)
  for (let i = 0; i < s.length; i++) {
    arr[s.charCodeAt(i) - 'a'.charCodeAt()]++
  }
  for (let i = 0; i < t.length; i++) {
    arr[t.charCodeAt(i) - 'a'.charCodeAt()]--
    if (arr[t.charCodeAt(i) - 'a'.charCodeAt()] < 0) {
      return false
    }
  }
  return true
};

复杂度分析

  • 时间复杂度:O(n),其中 n 为 s 的长度。
  • 空间复杂度:O(S),其中 S 为字符集大小,此处 S=26。

进阶

如果输入字符串包含 unicode 字符怎么办?

var isAnagram = function(s, t) {
  if (s.length !== t.length) {
    return false
  }
  let map = new Map() // 定义哈希表
  for(const ch of s){
    map.set(ch, (map.get(ch) || 0) + 1)
  }
  for(const ch of t){
    map.set(ch, (map.get(ch) || 0) - 1)
    if (map.get(ch) < 0) {
      return false
    }
  }
  return true
};

参考