859. 亲密字符串

90 阅读1分钟

给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。

交换字母的定义是:取两个下标 i 和 j (下标从 0 开始)且满足 i != j ,接着交换 s[i] 和 s[j] 处的字符。

例如,在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad"

思路

思路

如果 A[i] == B[i],我们就说 i 是匹配的,否则称 i 是不匹配的。亲密字符串几乎是完全匹配的,因为一次交换只会影响到两个索引。

如果交换 A[i] 和 A[j] 可以证明 A 和 B 是亲密字符串,那么就有 A[i] == B[j] 以及 A[j] == B[i]。 这意味着在 A[i], A[j], B[i], B[j] 这四个自由变量中,只存在两种情况:A[i] == A[j] 或 A[i] != A[j]

算法

算法

在 A[i] == A[j] == B[i] == B[j] 的情况下,字符串 A 与 B 相等。因此,如果 A == B,我们应当检查每个索引 i 以寻找具有相同值的两个匹配。

在 A[i] == B[j], A[j] == B[i], (A[i] != A[j]) 的情况下,其余索引是相匹配的。所以如果 A 和 B 只有两个不匹配的索引(记作 i 和 j),我们应该检查并确保等式 A[i] == B[j] 和 A[j] == B[i] 成立。

代码

var buddyStrings = function(A, B) {
    //A,B长度不相等且长度小于2的 或 A,B至少有一个是空串,两种情况直接false
    if(A.length !== B.length || A.length < 2){
        return false
    }
         
    //定义count变量,用于记录相对位置字符不同的数量
    let count = 0
    let arr1 = new Array()
    let arr2 = new Array()
    //循环字符串,对AB 相对应的索引 的元素进行比较
    for(let i=0;i<A.length;i++){
        if(A[i] !== B[i])
            count++
        if(count === 1)
            arr1.push(i)
        if(count === 2)
            arr2.push(i)
    }
     
    //count === 0代表AB两个字符串完全相同,但是必须有重复字符串才可以进行交换
    if(count === 0)
        return new Set(A).size < A.length
    if(count === 1 || count > 2){
        return false
    }else{
            return A[arr1[0]]===B[arr2[0]] && B[arr1[0]]===A[arr2[0]]
    }   
};