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

标签: 哈希表 字符串 计数

难度: Easy

给你长度相等的两个字符串 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
  • s1s2 仅由小写英文字母组成

Submission

运行时间: 24 ms

内存: 16.6 MB

class Solution:
    def areAlmostEqual(self, s1: str, s2: str) -> bool:
        a = ''
        b = ''
        n1 = len(s1)
        i = 0
        c = 0
        while i < len(s1):
            if s1[i] != s2[i]:
                if c > 1:
                    return False
                if c == 0:
                    c = 1
                    a = s1[i]
                    b = s2[i]
                else:
                    c = 2
                    if s1[i] != b or s2[i] != a:
                        return False
                    
            i += 1
        return c != 1

Explain

题解的思路是通过一次遍历两个字符串,记录下所有位置上字符不相同的情况。使用两个变量a和b来存储第一次发现的不匹配字符,如果在遍历过程中发现第二对不匹配的字符,会检查这对字符是否能通过一次交换与前一对不匹配的字符匹配(即 s1[i] 应等于之前的 b 且 s2[i] 应等于之前的 a)。如果能够匹配,继续检查是否有更多不匹配,如果有,则直接返回 false。如果整个遍历完成后只发现一对或没有不匹配的字符,返回 true。

时间复杂度: O(n)

空间复杂度: O(1)

# 方法定义:检查通过最多一次交换使两字符串相等

def areAlmostEqual(self, s1: str, s2: str) -> bool:
    a = ''  # 存储第一次不匹配时 s1 的字符
    b = ''  # 存储第一次不匹配时 s2 的字符
    n1 = len(s1)  # 字符串长度
    i = 0  # 初始索引
    c = 0  # 不匹配计数器
    while i < len(s1):  # 遍历字符串
        if s1[i] != s2[i]:  # 当前字符不匹配
            if c > 1:  # 已有两处不匹配
                return False
            if c == 0:  # 第一处不匹配
                c = 1
                a = s1[i]
                b = s2[i]
            else:  # 第二处不匹配
                c = 2
                if s1[i] != b or s2[i] != a:  # 检查是否可以通过一次交换匹配
                    return False
        i += 1  # 移动到下一个字符
    return c != 1  # 如果恰好一处不匹配,则返回 False,否则 True

Explore

该算法不能正确处理存在多于两处不匹配的情况。算法的设计是基于当出现多于两个不匹配的位置时,无法通过一次交换使两个字符串相等的假设。如果真实场景中存在多于两个不匹配但可以通过一次交换解决的情况,该算法会错误地返回 false。

这种判断是基于两处不匹配且这两处可以通过互换各自的字符来匹配的特殊情况。如果`s1[i]`等于之前的`b`且`s2[i]`等于之前的`a`,则这两个位置的字符完全可以通过一次交换来匹配。该逻辑很简单,且在这个特定场景中有效,不适用于更复杂的交换情况。该算法假设除了这两个不匹配外,其他位置的字符都是匹配的。

根据该算法的设计,如果在处理完这两处不匹配的情况后仍然存在其他不匹配的字符,算法将返回 false。该算法基于的假设是,要么不存在不匹配的字符,要么存在的不匹配可以仅通过一次交换解决。因此,存在更多不匹配的情况不符合算法设计的前提,因此返回 false 是符合逻辑的。

是的,这种逻辑在假设只有两处或没有不匹配的情况下是准确的。如果`c`的值不是1,意味着没有不匹配的字符或者有两处不匹配的字符且可以通过一次交换解决。这是因为如果有不匹配的字符且无法通过交换解决,`c`将会为1,此时返回 false。因此,这样的逻辑在规定的假设下是有效的。