1790. 仅执行一次字符串交换能否使两个字符串相等

121 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情

题目 leetcode.cn/

  • 给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。
  • 如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。

示例

  • 示例 1:

    • 输入: s1 = "bank", s2 = "kanb"
    • 输出: true
    • 解释: 例如,交换 s2 中的第一个和最后一个字符可以得到 "bank"
  • 示例 2:

    • 输入: s1 = "attack", s2 = "defend"
    • 输出: false
    • 解释: 一次字符串交换无法使两个字符串相等
  • 示例 3:

    • 输入: s1 = "kelb", s2 = "kelb"
    • 输出: true
    • 解释: 两个字符串已经相等,所以不需要进行字符串交换
  • 示例 4:

    • 输入: s1 = "abcd", s2 = "dcba"
    • 输出: false

提示

  • 1 <= s1.length, s2.length <= 100
  • s1.length == s2.length
  • s1 和 s2 仅由小写英文字母组成

代码

function areAlmostEqual(s1: string, s2: string): boolean {
    if(s1 === s2) return true;
    let index = [];
    for(let i = 0; i < s1.length; i++){
        if(s1[i] !== s2[i]){
            index.push(i);
        }
    }
    if(index.length > 2) return false;
    let s2Str = s2.split('');
    // 交换位置
    let temp = '';
    temp = s2Str[index[0]];
    s2Str[index[0]] = s2Str[index[1]];
    s2Str[index[1]] = temp;
    let s2s = s2Str.join('');
    return s1 === s2s ? true : false;
};
  • 首先分析下返回true的几种情况:
    • 对某个字符串的两个单独的字符进行一次位置交换后等于另一个字符串
    • 给定的两个字符串本来就相等,不需要交换字符串位置
  • 首先可以先判断s1是否等于s2,如果相等,那么直接返回true,不再进行后续操作了
  • 然后,遍历字符串(遍历s1或者s2都可以),如果能够通过交换一次得到两个字符串相等,那么无论是交换s1还是交换s2结果都是一样的。
  • 遍历判断两个字符串相同位置上的字符是否相等,如果不相等,那么这个位置可能就是后面要进行交换的位置,把不相等的位置记录下来
  • 得到所有不相等的位置坐标后,判断不相等字符个数。如果大于2个,那么一定无法通过只交换一次就能实现两个字符串相等的,最少是两次或者两次以上。
  • 排除上面情况后,最后得到的一定是两个不相等字符的下标。把这两个下标位置的字符交换位置,再判断两个字符串是否相等即可。
  • 字符串没办法直接替换下标字符,所以这里先拆分成字符串数组,交换后再拼接成字符串的