[路飞]_LeetCode_859. 亲密字符串

184 阅读2分钟

这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

题目

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

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

来源:力扣(LeetCode)leetcode-cn.com/problems/bu…

解题思路

  1. 暴力破解,依次取 s 中的两个字符交换位置,再和 goal 对比,如果相等则是亲密字符串。(力扣给了个超长字符串,结果超时了)
  2. 暴破不行就找规律,亲密字符串应该满足以下条件:
    • 两个字符串 长度 必须相等
    • 两个字符串完全相等时:
      • 有重复字符时则 是亲密字符串,可以交换重复位置的字符,譬如
        1. aabcd
        2. aabcd
      • 没有重复字符则不是亲密字符串,无论交换哪两个位置,交换后的字符串都不会和原来的字符串相等,譬如
        1. abcd
        2. abcd
    • 两个字符串不相等时:
      • 只有一个位置字符不相等时,不是亲密字符串,因为这个不相等的字符到了新位置会引起新的不相等,譬如
        1. abccd
        2. abbcd
      • 有三个或以上位置字符不相等时,不是亲密字符串,因为只能交换两个,譬如
        1. abcdefgh
        2. abddeagc
      • 有两个位置不相等,但满足s[第一个位置] = goal[第二个位置] 并且 s[第二个位置] = goal[第一个位置]时, 是亲密字符串,譬如
        1. aaaaabaacde
        2. aaaaacaabde

代码实现

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]
    }
};

如有错误欢迎指出,欢迎一起讨论!