Given two strings `A` and `B` of lowercase letters, return `true` if and only if we can swap two letters in `A` so that the result equals `B`.
Example 1:
Input: A = "ab", B = "ba"
Output: true
Example 2:
Input: A = "ab", B = "ab"
Output: false
Example 3:
Input: A = "aa", B = "aa"
Output: true
Example 4:
Input: A = "aaaaaaabc", B = "aaaaaaacb"
Output: true
Example 5:
Input: A = "", B = "aa"
Output: false
Note:
0 <= A.length <= 200000 <= B.length <= 20000AandBconsist only of lowercase letters.
這道題給了兩個字符串A和B,說是我們必須調換A中的兩個字符的位置一次,問是否能得到字符串B。這道題給的例子又多又全,基本上把所有的 corner cases 都覆蓋了,比如我們對比例子2和例子3,可以發現雖然兩個例子中A和B字符串都相等,但是仔細觀察的話,可以發現 "ab" 中沒有相同的字符,而 "aa" 中有相同的字符,那么實際上 "aa" 是可以調換兩個字符的位置的,這樣還跟字符串B相等,是符合題意的,因為題目要求必須要調換一次位置,若沒有相同的字符,是無法調換位置后和B相等的。
那么我們應該可以總結出一些規律了,首先字符串A和B長度必須要相等,不相等的話直接返回 false。假如起始時A和B就完全相等,那么只有當A中有重復字符出現的時候,才能返回 true。快速檢測重復字符的方法就是利用 HashSet 的自動去重復功能,將A中所有字符存入 HashSet 中,若有重復字符,那么最終 HashSet 的大小一定會小於原字符串A的長度。對於A和B長度相等,但是字符串本身不相等的一般情況,我們可以記錄出所有對應字符不相同的位置,放到一個數組 diff 中,最終判斷 diff 數組的長度是否為2,且判斷交換位置后是否跟B中對應的位置上的字符相同即可,參見代碼如下:
class Solution {
public:
bool buddyStrings(string A, string B) {
if (A.size() != B.size()) return false;
if (A == B && unordered_set<char>(A.begin(), A.end()).size() < A.size()) return true;
vector<int> diff;
for (int i = 0; i < A.size(); ++i) {
if (A[i] != B[i]) diff.push_back(i);
}
return diff.size() == 2 && A[diff[0]] == B[diff[1]] && A[diff[1]] == B[diff[0]];
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/859
參考資料:
https://leetcode.com/problems/buddy-strings/
https://leetcode.com/problems/buddy-strings/discuss/141780/Easy-Understood
[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
