859. Buddy Strings*

859. Buddy Strings*

https://leetcode.com/problems/buddy-strings/

题目描述

Given two strings A and B of lowercase letters, return true if and only if we can swap two letters in A so that the result equals B.

Example 1:

Input: A = "ab", B = "ba"
Output: true

Example 2:

Input: A = "ab", B = "ab"
Output: false

Example 3:

Input: A = "aa", B = "aa"
Output: true

Example 4:

Input: A = "aaaaaaabc", B = "aaaaaaacb"
Output: true

Example 5:

Input: A = "", B = "aa"
Output: false

Note:

  • 0 <= A.length <= 20000
  • 0 <= B.length <= 20000
  • A and B consist only of lowercase letters.

C++ 实现 1

这道题的需要注意题目中描述的 if and only if, 即 A 中的字符必须交换一次. 下面代码的思路是, 采用对撞指针, 找到 A[l] != B[l] 以及 A[r] != B[r], 并交换 std::swap(A[l], A[r]), 使用 swap_time 记录交换的次数.

然而, 由于必须交换 1 次, 那么遇到 A = "aa", B = "aa" 这样的情况 (即 AB 完全相等), 上面的思路就会出错. 因此需要对上面的思路进行修正. 观察发现, 如果 AB 完全相等, 那么只要 A 中存在两个字符相等, 就可以交换这两个字符, 比如 A = "aba", B = "aba" 这个例子, 可以交换两个 a; 而对于 A = "ab", B = "ab" 这个例子, 由于 A 中不存在两个相等的字符, 没法进行一次交换, 就需要返回 false.

为了检测 A 中是否存在两个相同的字符, 使用哈希表记录 A 中的字符个数, 并用 max_num 记录字符最大的个数. 当 AB 完全相等(此时 l > r && swap_time = 0), 只有当 max_num > 1 时才返回 true.

class Solution {
public:
    bool buddyStrings(string A, string B) {
        if (A.size() < 2 || B.size() < 2 || A.size() != B.size()) return false;
        int l = 0, r = A.size() - 1;
        int swap_time = 0, max_num = 0;
        unordered_map<char, int> record;
        while (l <= r) {
            while (l <= r && A[l] == B[l]) {
                record[A[l]] ++;
                max_num = std::max(max_num, record[A[l]]);
                ++ l;
            }
            while (l <= r && A[r] == B[r]) {
                record[A[r]] ++;
                max_num = std::max(max_num, record[A[r]]);
                -- r;
            }
            if (l > r) {
                // 两序列完全相等, 但无相同字母
                if ((swap_time == 0 && max_num < 2) || swap_time > 1) return false; 
                else return true;
            }
            std::swap(A[l], A[r]);
            if (++swap_time > 1) return false;
        }
        if ((swap_time == 0 && max_num < 2) || swap_time > 1) return false; 
        else return true;
    }
};

C++ 实现 2

来自 Easy Understood. 思路和 C++ 实现 1 一样, 但是更为清晰, 代码更为简洁.

If A.length() != B.length(): no possible swap

If A == B, we need swap two same characters. Check is duplicated char in A.

In other cases, we find index for A[i] != B[i]. There should be only 2 diffs and it’s our one swap.

class Solution {
public:
	bool buddyStrings(string A, string B) {
        if (A.length() != B.length()) return false;
        if (A == B && set<char>(A.begin(), A.end()).size() < A.size()) return true;
        vector<int> dif;
        for (int i = 0; i < A.length(); ++i) if (A[i] != B[i]) dif.push_back(i);
        return dif.size() == 2 && A[dif[0]] == B[dif[1]] && A[dif[1]] == B[dif[0]];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值