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

57 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

每日刷题 2022.10.11

题目

  • 给你长度相等的两个字符串s1s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。
  • 如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 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 仅由小写英文字母组成

解题思路

  • 计数:无需知道排好后的字符串长什么样,或者具体的哪几个不同。因此一旦超过2个不同就可以直接返回false。将不同的位置记录下来,最终比较这两个字符交换是否相同。
  • 这道题目很简单,题目说的很明显,s1s2 只能有两个字符不同,而且 s1s2不同的那两个字符交换位置后,字符串 s1s2 相等。
  • 所以,只需要遍历一遍就可以,提前申请两个字符串变量用于记录不同的字符,在记录的过程中,对于 s1 s2 不同的字符,加到 s1 对应字符串变量的后面,加到 s2 对应字符串变量的前面。结束的时候,判断二者的长度是否等于 2 并且相等就行了。
  • 对于 s1s2 相等的情况,直接返回 true 即可。

AC代码

/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var areAlmostEqual = function(s1, s2) {
  // 使用diff数组
  let diff = [];
  for(let i = 0, n = s1.length; i < n; i++) {
    if(s1[i] != s2[i]) {
      if(diff.length >= 2) return false;
      else diff.push(i);
    }
  }
  // 长度1
  let len = diff.length;
  if(len === 1) return false;
  if(len === 0) return true;
  return s1[diff[0]] === s2[diff[1]] && s1[diff[1]] === s2[diff[0]];
};