class Solution:
def buddyStrings(self, s: str, goal: str) -> bool:
if len(s) != len(goal):
return False
if s == goal:
seen = set()
for c in s:
if c in seen:
return True
seen.add(c)
return False
diffs = []
for i in range(len(s)):
if s[i] != goal[i]:
diffs.append(i)
if len(diffs) != 2:
return False
i, j = diffs
return s[i] == goal[j] and s[j] == goal[i]
class Solution {
public:
bool buddyStrings(string s, string goal) {
if (s.length() != goal.length()) return false;
if (s == goal) {
vector<int> count(26, 0);
for (char c : s) {
count[c - 'a']++;
if (count[c - 'a'] > 1) return true;
}
return false;
}
vector<int> diff;
for (int i = 0; i < s.length(); ++i) {
if (s[i] != goal[i]) diff.push_back(i);
}
if (diff.size() != 2) return false;
return s[diff[0]] == goal[diff[1]] && s[diff[1]] == goal[diff[0]];
}
};
class Solution {
public boolean buddyStrings(String s, String goal) {
if (s.length() != goal.length()) return false;
if (s.equals(goal)) {
int[] count = new int[26];
for (char c : s.toCharArray()) {
count[c - 'a']++;
if (count[c - 'a'] > 1) return true;
}
return false;
}
List<Integer> diff = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != goal.charAt(i)) diff.add(i);
}
if (diff.size() != 2) return false;
int i = diff.get(0), j = diff.get(1);
return s.charAt(i) == goal.charAt(j) && s.charAt(j) == goal.charAt(i);
}
}
var buddyStrings = function(s, goal) {
if (s.length !== goal.length) return false;
if (s === goal) {
let seen = new Set();
for (let c of s) {
if (seen.has(c)) return true;
seen.add(c);
}
return false;
}
let diffs = [];
for (let i = 0; i < s.length; i++) {
if (s[i] !== goal[i]) diffs.push(i);
}
if (diffs.length !== 2) return false;
let [i, j] = diffs;
return s[i] === goal[j] && s[j] === goal[i];
};
You are given two strings, s
and goal
, of the same length. Your task is to determine if you can swap exactly two letters in s
so that it becomes equal to goal
. The swap must involve two different indices (i.e., you cannot swap a letter with itself at the same position), and you can perform at most one swap.
Key constraints:
s
at most once.s
is already equal to goal
, you can only return true
if there is at least one duplicate letter in s
(so a swap can be made that leaves the string unchanged).true
if it's possible to make s
equal to goal
with one swap, and false
otherwise.
At first glance, the problem seems to require checking all possible pairs of swaps in s
to see if any result in goal
. However, this brute-force approach would be inefficient, especially for long strings.
Upon further consideration, we can optimize by observing:
s
and goal
are not the same length, it's impossible to make them equal.s
is already equal to goal
, we need to check for duplicate characters. Only then can we swap two identical letters and still have the same string.s
and goal
differ, we should look for exactly two positions where their characters differ. Swapping these two characters in s
should make the strings equal.Let's break down the algorithm step by step:
s
and goal
are not the same length, return false
immediately.
s
is equal to goal
:
s
for duplicate characters.true
(since swapping them keeps the string unchanged).false
(since a swap would alter the string).s
and goal
are not equal:
s
would make the strings equal.true
; otherwise, return false
.false
.We use a set or an array to check for duplicate letters efficiently (O(n) time). We only need to store up to two indices where the characters differ, so space usage is minimal.
Let's consider the example: s = "ab"
, goal = "ba"
.
s
and goal
are not equal, so we look for differences:
s[0] = 'a'
, goal[0] = 'b'
(different)s[1] = 'b'
, goal[1] = 'a'
(different)s[0]
and s[1]
will result in goal
:
s
to get "ba", which matches goal
.true
.
Another example: s = "aa"
, goal = "aa"
.
true
.
If s = "ab"
, goal = "ab"
:
false
.Brute-force Approach:
The optimized approach is much more efficient and suitable for large inputs.
To solve the Buddy Strings problem efficiently, we: