题目描述:
给定两个由小写字母构成的字符串 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
仅由小写字母构成。
方法分析:
首先,根据亲密字符串的定义,交换其中一个字符串的一对字母能得到与另一个字符串的结果,则被称为亲密字符串。也就是说,有以下要点能被提炼出来:
- 亲密字符串一定是两个长度相等的字符串,若长度不等,不可能为亲密字符串
- 由于是相邻交换,故亲密字符串的不同字符对数只能为 2 对或者 0 对
- 0 对指的是两个字符串完全相同,此时只要字符串中存在重复字符,其就互为亲密字符串
- 对于 2 对的情况,我们还需判断这两对不同字符交换的结果是否一致,如果一致,则为亲密字符串
代码实现:
var buddyStrings = function(A, B) {
let lenA = A.length, lenB = B.length;
let diff = [];
//若两个字符串长度不等,肯定不是亲密字符串
if(lenA != lenB) return false;
//若两个字符串完全相等,则判断有无重复字符
if(A == B && new Set(A.split("")).size < lenA ) return true;
//找出不同字符的索引
for(let i in A) {
if(A[i] != B[i]) diff.push(i);
}
//当不同字符对数为2且交叉位置相等,则为亲密字符串
if(diff.length == 2 && A[diff[0]] == B[diff[1]] && A[diff[1]] == B[diff[0]]) return true;
return false;
};
代码解析:
在上述代码中,我们对三种情况进行了判断。这三种情况,此处就不再解释,方法分析 和 代码注释 中已经展现了。这里说说代码。在判断有无重复字符处,我利用了ES6的集合(set)。集合中的元素具有唯一性,它会对传入其中的数据进行去重处理。利用集合来判断有无重复元素和去重, 是一种很好的做法。
for...in循环是对键的遍历,for...of循环是对值的遍历。对数组而言,for...in遍历的是索引,而for...of遍历的是数组每项的值。
该算法的时间复杂度为 ,其中为字符串的长度。
该算法的空间复杂度为,其中为字符串的长度。
相关链接:https://leetcode-cn.com/problems/buddy-strings/description/