【力扣】859. 亲密字符串

以下为力扣官方题解,以及本人代码

859. 亲密字符串

  • 题目
  • 示例1
  • 示例2
  • 示例3
  • 示例4
  • 示例5
  • 提示
  • 官方题解 情况列举
    • 思路
    • 算法
  • 本人代码
    • 复杂度分析

题目

给定两个由小写字母构成的字符串 A A A B B B ,只要我们可以通过交换 A A A 中的两个字母得到与 B B B 相等的结果,就返回 t r u e true true;否则返回 f a l s e false false
交换字母的定义是取两个下标 i i i j j j (下标从 0 0 0 开始),只要 i ! = j i!=j i!=j 就交换 A [ i ] A[i] A[i] A [ j ] A[j] A[j] 处的字符。例如,在 “ a b c d abcd abcd” 中交换下标 0 0 0 和下标 2 2 2 的元素可以生成 “ c b a d cbad cbad”。

示例1

输入: A = " a b " , B = " b a " A = "ab", B = "ba" A="ab",B="ba"
输出: t r u e true true
解释: 你可以交换 A [ 0 ] = ′ a ′ A[0] = 'a' A[0]=a A [ 1 ] = ′ b ′ A[1] = 'b' A[1]=b 生成 " b a " "ba" "ba",此时 A A A B B B 相等。

示例2

输入: A = " a b " , B = " a b " A = "ab", B = "ab" A="ab",B="ab"
输出: f a l s e false false
解释: 你只能交换 A [ 0 ] = ′ a ′ A[0] = 'a' A[0]=a A [ 1 ] = ′ b ′ A[1] = 'b' A[1]=b 生成 “ b a ba ba”,此时 A A A B B B 不相等。

示例3

输入: A = " a a " , B = " a a " A = "aa", B = "aa" A="aa",B="aa"
输出: t r u e true true
解释: 你可以交换 A [ 0 ] = ′ a ′ A[0] = 'a' A[0]=a A [ 1 ] = ′ a ′ A[1] = 'a' A[1]=a 生成 “ a a aa aa”,此时 A A A B B B 相等。

示例4

输入: A = " a a a a a a a b c " , B = " a a a a a a a c b " A = "aaaaaaabc", B = "aaaaaaacb" A="aaaaaaabc",B="aaaaaaacb"
输出: t r u e true true

示例5

输入: A = " " , B = " a a " A = "", B = "aa" A="",B="aa"
输出: f a l s e false false

提示

  1. 0 < = A . l e n g t h < = 20000 0 <= A.length <= 20000 0<=A.length<=20000
  2. 0 < = B . l e n g t h < = 20000 0 <= B.length <= 20000 0<=B.length<=20000
  3. A 和 B 仅 由 小 写 字 母 构 成 A 和 B 仅由小写字母构成 AB

官方题解 情况列举

思路

如果 A [ i ] = = B [ i ] A[i] == B[i] A[i]==B[i],我们就说 i i i 是匹配的,否则称 i i i 是不匹配的。亲密字符串几乎是完全匹配的,因为一次交换只会影响到两个索引。

如果交换 A [ i ] A[i] A[i] A [ j ] A[j] A[j] 可以证明 A A A B B B 是亲密字符串,那么就有 A [ i ] = = B [ j ] A[i] == B[j] A[i]==B[j] 以及 A [ j ] = = B [ i ] A[j] == B[i] A[j]==B[i]。这意味着在 A [ i ] A[i] A[i] A [ j ] A[j] A[j] B [ i ] B[i] B[i] B [ j ] B[j] B[j] 这四个自由变量中,只存在两种情况: A [ i ] = = A [ j ] A[i] == A[j] A[i]==A[j] A [ i ] ! = A [ j ] A[i] != A[j] A[i]!=A[j]

算法

  1. A [ i ] = = A [ j ] = = B [ i ] = = B [ j ] A[i] == A[j] == B[i] == B[j] A[i]==A[j]==B[i]==B[j] 的情况下,字符串 A A A B B B 相等。因此,如果 A = = B A == B A==B,我们应当检查每个索引 i i i 以寻找具有相同值的两个匹配。
  2. A [ i ] = = B [ j ] A[i] == B[j] A[i]==B[j] A [ j ] = = B [ i ] A[j] == B[i] A[j]==B[i],( A [ i ] ! = A [ j ] A[i] != A[j] A[i]!=A[j])的情况下,其余索引是相匹配的。所以如果 A A A B B B 只有两个不匹配的索引(记作 i i i j j j),我们应该检查并确保等式 A [ i ] = = B [ j ] A[i] == B[j] A[i]==B[j] A [ j ] = = B [ i ] A[j] == B[i] A[j]==B[i] 成立。

本人代码

class Solution {
    public boolean buddyStrings(String A, String B) {
        // 如果字符串 A、B 长度不同,则不可能为亲密字符串
        if (A.length() != B.length())
            return false;
        
        // 如果 A、B 相同
        if (A.equals(B))
        {
            int[] count = new int[26];
            for (int i=0; i<A.length(); i++)    // 计算 A 中各个字母出现的次数
                count[A.charAt(i)-'a'] ++;
            
            for (int c : count)     // 如果有一个字母出现的次数大于 1,则 A 可以用其完成对调的要求
                if (c>1)
                    return true;
            return false;
        }
        // 如果 A、B 不同
        else
        {
            int first = -1, second = -1;
            for (int i=0; i<A.length(); i++)
                if (A.charAt(i) != B.charAt(i))
                {
                    if (first == -1)
                        first = i;
                    else if (second == -1)
                        second = i;
                    else
                        return false;   // 超过三处不同则无法达到题目要求
                }
            return (second!=-1 && A.charAt(first)==B.charAt(second) && A.charAt(second)==B.charAt(first));
        }
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n A A A B B B 的长度。
  • 空间复杂度: O ( 1 ) O(1) O(1)

你可能感兴趣的:(力扣,leetcode,java)