参加了 kkb 的门徒培训,想要记录下自己的成长过程。每天一篇,坚持不断更 --- 2022.3.17
题目描述
给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。
交换字母的定义是:取两个下标 i 和 j (下标从 0 开始)且满足 i != j ,接着交换 s[i] 和 s[j] 处的字符。
- 例如,在
"abcd"中交换下标0和下标2的元素可以生成"cbad"。
示例 1:
输入: s = "ab", goal = "ba"
输出: true
解释: 你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 相等。
示例 2:
输入: s = "ab", goal = "ab"
输出: false
解释: 你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 不相等。
示例 3:
输入: s = "aa", goal = "aa"
输出: true
解释: 你可以交换 s[0] = 'a' 和 s[1] = 'a' 生成 "aa",此时 s 和 goal 相等。
提示:
1 <= s.length, goal.length <= 2 * 104s和goal由小写英文字母组成
解题思路
这题需要考虑到,有两个以上的差异的可能。
/**
* @param {string} a
* @param {string} b
* @return {boolean}
*/
const isRepeat = (a) => {
const count = {};
for (let item of a) {
// 计数法判断是否有重复字符
count[item] = count[item] ? count[item] + 1 : 1;
if (count[item] === 2) return true;
}
return false;
};
var buddyStrings = function (a, b) {
if (a.length !== b.length) return false;
// 相等较为简单,但不一定满足可交换,判断下
if (a === b) return isRepeat(a);
// 找两处不同的地方,然后看是否只有两处,且这两处是字母交换位置
let i = 0,
j;
while (a[i] === b[i]) {
i++; // 第一处差异点
}
j = i + 1;
if (j > a.length) return false; // 差异为 false
while (j < a.length && a[j] == b[j]) {
j++;
}
// 只有一处差异
if (j == a.length) return false;
// 发现两处不相等
if (a[i] !== b[j] || a[j] !== b[i]) return false;
j++;
// 有三个以上的差异
while (j < a.length) {
if (a[j] != b[j]) return false;
j++;
}
return true;
};