题目描述
给定两个由小写字母构成的字符串 A
和 B
,只要我们可以通过交换 A
中的两个字母得到与 B
相等的结果,就返回 true
;否则返回 false
。
样例
输入: A = "ab", B = "ba"
输出: true
输入: A = "ab", B = "ab"
输出: false
输入: A = "aa", B = "aa"
输出: true
输入: A = "aaaaaaabc", B = "aaaaaaacb"
输出: true
输入: A = "", B = "aa"
输出: false
注意
0 <= A.length <= 20000
0 <= B.length <= 20000
A
和B
仅由小写字母构成。
算法
(模拟) $O(n)$
- 如果两个字符串长度不相等,则返回 false。
- 如果两个字符串有超过两处位置,其对应字符不一致,返回 false。
- 如果仅有两处位置字符不相同,则分别判断这两处位置交换后是否相同。
- 如果仅有一处位置字符不相同,则返回 false。
- 如果没有位置字符不相同,则根据题意,我们不得不找到两处位置交换。如果字符串中有两处位置字符相同,则返回 true;否则返回 false。
时间复杂度
- 每个字符串仅遍历常数次,故时间复杂度为 $O(n)$。
空间复杂度
- 如果两个字符串完全相同,我们需要一个长度为 26 的数组记录每个是否有重复的字符,其他变量仅需要常数的空间。故空间复杂度为 $O(1)$。
C++ 代码
class Solution {
public:
#define LL long long
bool buddyStrings(string A, string B) {
int n = A.length(), m = B.length();
if (n != m)
return false;
int pos1 = -1, pos2 = -1;
for (int i = 0; i < n; i++)
if (A[i] != B[i]) {
if (pos1 != -1) {
if (pos2 != -1)
return false;
pos2 = i;
}
else
pos1 = i;
}
if (pos1 == -1 && pos2 == -1) {
vector<int> letter(26, 0);
for (int i = 0; i < n; i++) {
letter[A[i] - 'a']++;
if (letter[A[i] - 'a'] >= 2)
return true;
}
return false;
}
if (pos1 != -1 && pos2 == -1)
return false;
if (A[pos2] != B[pos1] || A[pos1] != B[pos2])
return false;
return true;
}
};