[路飞]_leetcode刷题_859. 亲密字符串

162 阅读2分钟

题目

859. 亲密字符串

给你两个字符串 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 相等。

思路:

暴力解法,遍历整个字符串,把每两个字母交换位置,然后和goal比较。

/**
 * @param {string} s
 * @param {string} goal
 * @return {boolean}
 */
var buddyStrings = function(s, goal) {
    let arr = s.split('');
    for(let i=0;i<arr.length;i++){
        for(let j=i+1;j<arr.length;j++){
            [arr[i],arr[j]] =  [arr[j],arr[i]] 
            if(arr.join('') == goal){
                return true;
            }else{
                [arr[i],arr[j]] =  [arr[j],arr[i]] 
            }
        }
    }
    return false;
};

image.png

超时间限制, 那我们就改进方案:

两个字符字符串交换两个字符串后相当,只有以下两种情况:

  1. 两个字符串相等,且字符串内有重复字段。
  2. 字符串只有两个字符不一样,且s[i] == goal[j],s[j] == goal[i].

所以思路变换一下,

  1. 判断长度不等,直接return false
  2. 字符串一样,去重后长度小于原来长度,则说明有重复字段,则return true,否则return false
  3. 遍历字符串,找到不一样的元素的下标并记录下来
  4. 如果不一样的元素个数不为2,return false
  5. 如果个数为2,判断s[i] == goal[j] && s[j] == goal[i],return结果
/**
 * @param {string} s
 * @param {string} goal
 * @return {boolean}
 */
var buddyStrings = function(s, goal) {
    if(s.length != goal.length) return false;
    let arr_s = s.split('');
    let arr_goal = goal.split('');
    let diffIndex=[];
    let count = 0;
    if(s === goal){
        if(unique(arr_s).length<arr_s.length){
            return true;
        }else{
            return false;
        }
    }
    for(let i=0;i<arr_s.length;i++){
        if(arr_s[i] != arr_goal[i]){
            diffIndex.push(i);
            count++;
        }
    }
    if(count ==2){
        return arr_s[diffIndex[0]] == arr_goal[diffIndex[1]] && arr_s[diffIndex[1]] == arr_goal[diffIndex[0]]
    }else{
        return false;
    }

};

function unique(arr){
    return Array.from(new Set(arr))
}

这题令我惊讶的是,我以为看了题解会发现什么未知领域的知识,或者惊天大秘密,实际大家的写法虽然千奇百怪,但竟然都不怎么优雅。。。。