有效的字母异位词

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

示例 1:

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

示例 2:

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

说明:

你可以假设字符串只包含小写字母。

进阶:

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

解答

题目的意思是找两个字符串之间,是否出现的字符与次数相同,而与顺序无关。同时,题目中还包含了一个边界条件,即如果字符串中包含了 unicode 字符应该如何处理。

那么,首先需要考虑到 unicode 字符,则我们可以将每个字符都转为 ascii 码。

这样就将问题转化为求两个 int 数组之间是否出现的数字与次数相同。

其次,因为两个 int 数组之间必然存在排序后两两对应的情况,则如果两个字符串之间关系成立,则其 int 数组所有数字 异或 之后结果必为 0,此为判断条件一。

然后,由于存在有边界条件的情况,如两个字符串本身其异或值为0,如 aabb ,那么我们可以通过将 int 数组分别相乘,互相比较,如果相同则说明关系成立,此为条件二。

为什么不使用求和

这是因为,求和之间也可能存在有边界条件,如 xaaddyxbbccy。通过相乘来确保关系成立。

代码如下:

#include <iostream>
#include <cstring>

using namespace std;

// 优化输入输出效率
static auto x = []() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return 0;
}();

class Solution
{
  public:
    bool isAnagram(string s, string t)
    {
        int ret = 0;
        // int s_sum = 0;
        // int t_sum = 0;
        int s_times = 1;
        int t_times = 1;

        for (int i = 0; i < s.length(); i++)
        {
            int c = int(s[i]);
            ret ^= c;
            // s_sum += c;
            s_times *= c;
        }

        for (int i = 0; i < t.length(); i++)
        {
            int c = int(t[i]);
            ret ^= c;
            // t_sum += c;
            t_times *= c;
        }
        // return ret == 0 && s_sum == t_sum && s_times == t_times;
        return ret == 0 && s_times == t_times;
    }
};

值得一提的是以下这段代码:

// 优化输入输出效率
static auto x = []() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return 0;
}();

其原理为优化在多次执行入参的时候的执行效率,在性能提交上会与没有添加这段代码的代码差距在50% 以上,测试用例越多越明显。

当然这只是在 LeetCode 上提升排名的一个小方法,在实际环境中根据实际情况才可能会有提升效率的作用。:)

Comments !