给你两个字符串
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 相等。
示例 4:
输入:s = "aaaaaaabc", goal = "aaaaaaacb"
输出:true
首先要了解一下判断是否是亲密字符串的标准: 可以交换一个字符串中指定的两个字符,让其和另一个字符串完全相同,那么这两个字符串为亲密字符串。
特别需要注意的是:即使两个字符串完全相等,也未必是亲密字符串。因为亲密字符串一定是要通过交换某两个字符之后才能得到,完全相等的情况下,如果不能通过交换一次字符使其再次相等,那么也不构成亲密字符串。
那么我们要如何从逻辑上去定义亲密字符串呢?
亲密字符串的前提:长度相同
这一点不用解释了吧。如果长度不同,无论怎么交换,交换多少次,他们都不可能相等的,也就是不可能构成亲密字符串。
亲密字符串的特点: 字符串S1和S2里面有且只有2个字符会不一样,并且这两个字符相互对称
这一点怎么解释呢, 当他们长度相同时,我们只需要判断每一位上的字符是否一一对应的相同,亲密字符串一定最多只会出现2个不同的字符串,并且用来交换后相等。
图用来说明:
亲密字符串的特殊情况:完全相同
上面已经可以满足大部分的亲密字符串的判定。但为什么说是大部分的呢?举例说明:
S1: [a,a,b]
S2: [a,a,b]
S1和S2完全相同,也就是说在上图的逻辑来看,对应位置是找不出不同的字符的。那么这是不是亲密字符串呢?可以发现,将 S1 或 S2的第一个和第二个字符交换位置,依然可以相等于另一个字符串。
那么我们可以得出结论: 如果两个字符串完全相同,那么判断其中一个是否有重复的字符即可。(有重复字符交换后可以等于原来的字符串)
完整代码:
* @param {string} s
* @param {string} goal
* @return {boolean}
var isHasSameChar = function (s) {
s = s.split('')
return [...new Set(s)].length !== s.length
var buddyStrings = function(s, goal) {
if (s === goal) {
return isHasSameChar(s)
if (s.length !== goal.length) {
return false
let count = 0
let sList = []
let gLost = []
for (let index = 0
if (s[index] !== goal[index]) {
count++
if (count > 2) {
return false
sList.push(s[index])
gLost.push(goal[index])
if (count <= 1) {
return false
return sList[1] === gLost[0] && sList[0] === gLost[1]