Problem
Two strings are considered close if you can attain one from the other using the following operations:
- Operation 1: Swap any two existing characters.
- For example,
abcde -> aecdb
- For example,
- Operation 2: Transform every occurrence of one existing character into another existing character, and do the same with the other character.
- For example,
aacabb -> bbcbaa
(alla
’s turn intob
’s, and allb
’s turn intoa
’s)
- For example,
You can use the operations on either string as many times as necessary.
Given two strings, word1
and word2
, return true
if word1
and word2
are close, and false
otherwise.
Examples
Example 1:
Input: word1 = "abc", word2 = "bca"
Output: true
Explanation: You can attain word2 from word1 in 2 operations.
Apply Operation 1: "abc" -> "acb"
Apply Operation 1: "acb" -> "bca"
Example 2:
Input: word1 = "a", word2 = "aa"
Output: false
Explanation: It is impossible to attain word2 from word1, or vice versa, in any number of operations.
Example 3:
Input: word1 = "cabbba", word2 = "abbccc"
Output: true
Explanation: You can attain word2 from word1 in 3 operations.
Apply Operation 1: "cabbba" -> "caabbb"
`Apply Operation 2: "`caabbb" -> "baaccc"
Apply Operation 2: "baaccc" -> "abbccc"
Solution
Method 1 - Using map and sorting
To determine if two strings are close, we need to check
- Both strings must have the same set of characters.
- The frequency of each character must match, but the specific characters can be permuted.
So, here si the approach:
- Check if both strings have the same length.
- Count the frequency of each character in both strings.
- Check if the sets of characters in both strings are identical.
- Check if the sorted frequency lists of both strings are identical.
Code
Java
public class Solution {
public boolean closeStrings(String word1, String word2) {
if (word1.length() != word2.length()) {
return false;
}
int[] count1 = new int[26];
int[] count2 = new int[26];
for (char c : word1.toCharArray()) {
count1[c - 'a']++;
}
for (char c : word2.toCharArray()) {
count2[c - 'a']++;
}
// Check if both strings have the same set of characters
for (int i = 0; i < 26; i++) {
if ((count1[i] == 0 && count2[i] != 0) || (count1[i] != 0 && count2[i] == 0)) {
return false;
}
}
Arrays.sort(count1);
Arrays.sort(count2);
return Arrays.equals(count1, count2);
}
}
Python
class Solution:
def closeStrings(self, word1: str, word2: str) -> bool:
if len(word1) != len(word2):
return False
count1 = [0] * 26
count2 = [0] * 26
for ch in word1:
count1[ord(ch) - ord('a')] += 1
for ch in word2:
count2[ord(ch) - ord('a')] += 1
# Check if the sets of characters are identical
for i in range(26):
if (count1[i] == 0 and count2[i] != 0) or (count1[i] != 0 and count2[i] == 0):
return False
count1.sort()
count2.sort()
return count1 == count2
Complexity
- ⏰ Time complexity:
O(n + m)
wheren
is the length ofword1
andm
is the length ofword2
. - 🧺 Space complexity:
O(1)
since we use fixed space for character counts (assuming a constant alphabet size of 26).