这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战」
题目
给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。
交换字母的定义是:取两个下标 i 和 j (下标从 0 开始)且满足 i != j ,接着交换 s[i] 和 s[j] 处的字符。
来源:力扣(LeetCode)leetcode-cn.com/problems/bu…
解题思路
- 暴力破解,依次取 s 中的两个字符交换位置,再和 goal 对比,如果相等则是亲密字符串。(力扣给了个超长字符串,结果超时了)
- 暴破不行就找规律,亲密字符串应该满足以下条件:
- 两个字符串 长度 必须相等
- 两个字符串完全相等时:
- 有重复字符时则 是亲密字符串,可以交换重复位置的字符,譬如
aa
bcdaa
bcd
- 没有重复字符则不是亲密字符串,无论交换哪两个位置,交换后的字符串都不会和原来的字符串相等,譬如
- abcd
- abcd
- 有重复字符时则 是亲密字符串,可以交换重复位置的字符,譬如
- 两个字符串不相等时:
- 只有一个位置字符不相等时,不是亲密字符串,因为这个不相等的字符到了新位置会引起新的不相等,譬如
- ab
c
cd - ab
b
cd
- ab
- 有三个或以上位置字符不相等时,不是亲密字符串,因为只能交换两个,譬如
- ab
c
def
gh
- ab
d
dea
gc
- ab
- 有两个位置不相等,但满足s[第一个位置] = goal[第二个位置] 并且 s[第二个位置] = goal[第一个位置]时, 是亲密字符串,譬如
- aaaaa
b
aac
de - aaaaa
c
aab
de
- aaaaa
- 只有一个位置字符不相等时,不是亲密字符串,因为这个不相等的字符到了新位置会引起新的不相等,譬如
代码实现
var buddyStrings = function(s, goal) {
//暴力求解(力扣给了个超长字符串,超时了)
//0 和 1,2,3, ... n - 1 交换后对比
//1 和 2,3,4, ... n - 1 交换后对比
//n - 2 和 n - 1 交换后对比
// for (let i = 0; i < len; i++) {
// for (let j = i + 1; j < len; j++) {
// let tmp = s.split('');
// [tmp[i], tmp[j]] = [tmp[j], tmp[i]]
// if (tmp.join('') === goal) return true
// }
// }
//剪枝,长度不相等的肯定不是亲密字符串
if (s.length !== goal.length) return false
if (s === goal) {
//两个相同字符串中存在相同字符就是亲密字符串
const map = new Map()
for (let c of s) {
if (map.has(c)) return true
map.set(c, c)
}
return false
} else {
//找到两个字符串的第1个不同字符和第2个不同字符
//判断s第一个是否等于goal第2个字符
//goal第2个字符是否等于s第一个字符
//如果两个判断都为 true 则是亲密字符串
const len = s.length
let first = second = -1
for (let i = 0; i < len; i++) {
if (s[i] !== goal[i]) {
if (first === -1) first = i
else if (second === -1) second = i
else return false
}
}
return first !== -1 && second != -1
&& s[first] === goal[second] && s[second] === goal[first]
}
};
如有错误欢迎指出,欢迎一起讨论!