有效的字母异位词 242

28 阅读2分钟

力扣 242 有效的字母异位词

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= s.length, t.length <= 5 * 104
  • s 和 t 仅包含小写字母

解法一 排序解法

这道题的本质是看两个字符串包含的各字母数量是否一样,如果两个字符串是符合条件的,那一定是顺序不同但是各类元素个数相同的。基于此,就考虑先排序再比较,排序后如果两个字符串一样,那说明肯定是有效的。

✅排序解法的代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        sort(s.begin(), s.end());
        sort(t.begin(), t.end());
        return s == t;
	}
};

排序解法比较好理解,同时代码短容易操作,但其时间复杂度为 O(nlogn) ,因此不是最优解。


解法二 哈希数组

数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串 s 里字符出现的次数。

定义一个长度为 26 的数组,用于记录次数,s 中元素每出现一次就在对应索引处加一。

✅哈希数组解法的代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        for(int i = 0;i < s.size();i++){
            record[s[i] - 'a']++;
        }
        for(int i = 0;i < t.size();i++){
            record[t[i] - 'a']--;
        }
        for(int i = 0;i < 26;i++){
            if(record[i] != 0){
                return false;
            }
        }
    return true;    
    }
};

核心思路

  • 首先定义 record 数组,长度为 26 ,用于记录出现次数
  • 先对 s 进行遍历记录,因为在数组中 a 对应为 0,所以只需要**用当前字母减 a **即可得到对应数组索引值,也就是不需要知道准确的 ASCLL 。每个字母出现一次,便在对应索引处加一
  • 再对 t 遍历记录,同样,每个字母出现一次便对应索引减一
  • 最后检查 record 数组每个元素是否为零,为零则有效,否则无效

该解法时间复杂度O(n) ,明显优化。