有效的字母异位词
给定两个字符串 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,如 aa 与 bb ,那么我们可以通过将 int 数组分别相乘,互相比较,如果相同则说明关系成立,此为条件二。
为什么不使用求和
这是因为,求和之间也可能存在有边界条件,如 xaaddy 与 xbbccy。通过相乘来确保关系成立。
代码如下:
#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 !