2506. Count Pairs Of Similar Strings
Description
You are given a 0-indexed string array words
.
Two strings are similar if they consist of the same characters.
- For example,
"abca"
and"cba"
are similar since both consist of characters'a'
,'b'
, and'c'
. - However,
"abacba"
and"bcfd"
are not similar since they do not consist of the same characters.
Return the number of pairs (i, j)
such that 0 <= i < j <= word.length - 1
and the two strings words[i]
and words[j]
are similar.
Example 1:
Input: words = ["aba","aabb","abcd","bac","aabc"] Output: 2 Explanation: There are 2 pairs that satisfy the conditions: - i = 0 and j = 1 : both words[0] and words[1] only consist of characters 'a' and 'b'. - i = 3 and j = 4 : both words[3] and words[4] only consist of characters 'a', 'b', and 'c'.
Example 2:
Input: words = ["aabb","ab","ba"] Output: 3 Explanation: There are 3 pairs that satisfy the conditions: - i = 0 and j = 1 : both words[0] and words[1] only consist of characters 'a' and 'b'. - i = 0 and j = 2 : both words[0] and words[2] only consist of characters 'a' and 'b'. - i = 1 and j = 2 : both words[1] and words[2] only consist of characters 'a' and 'b'.
Example 3:
Input: words = ["nba","cba","dba"] Output: 0 Explanation: Since there does not exist any pair that satisfies the conditions, we return 0.
Constraints:
1 <= words.length <= 100
1 <= words[i].length <= 100
words[i]
consist of only lowercase English letters.
Solutions
Solution 1: Hash Table + Bit Manipulation
For each string, we can convert it into a binary number of length $26$, where the $i$-th bit being $1$ indicates that the string contains the $i$-th letter.
If two strings contain the same letters, their binary numbers are the same. Therefore, for each string, we use a hash table to count the occurrences of its binary number. Each time we add the count to the answer, then increment the count of its binary number by $1$.
The time complexity is $O(L)$, and the space complexity is $O(n)$. Here, $L$ is the total length of all strings, and $n$ is the number of strings.
Python3
class Solution:
def similarPairs(self, words: List[str]) -> int:
ans = 0
cnt = Counter()
for s in words:
x = 0
for c in map(ord, s):
x |= 1 << (c - ord("a"))
ans += cnt[x]
cnt[x] += 1
return ans
Java
class Solution {
public int similarPairs(String[] words) {
int ans = 0;
Map<Integer, Integer> cnt = new HashMap<>();
for (var s : words) {
int x = 0;
for (char c : s.toCharArray()) {
x |= 1 << (c - 'a');
}
ans += cnt.merge(x, 1, Integer::sum) - 1;
}
return ans;
}
}
C++
class Solution {
public:
int similarPairs(vector<string>& words) {
int ans = 0;
unordered_map<int, int> cnt;
for (const auto& s : words) {
int x = 0;
for (auto& c : s) {
x |= 1 << (c - 'a');
}
ans += cnt[x]++;
}
return ans;
}
};
Go
func similarPairs(words []string) (ans int) {
cnt := map[int]int{}
for _, s := range words {
x := 0
for _, c := range s {
x |= 1 << (c - 'a')
}
ans += cnt[x]
cnt[x]++
}
return
}
TypeScript
function similarPairs(words: string[]): number {
let ans = 0;
const cnt = new Map<number, number>();
for (const s of words) {
let x = 0;
for (const c of s) {
x |= 1 << (c.charCodeAt(0) - 97);
}
ans += cnt.get(x) || 0;
cnt.set(x, (cnt.get(x) || 0) + 1);
}
return ans;
}
Rust
use std::collections::HashMap;
impl Solution {
pub fn similar_pairs(words: Vec<String>) -> i32 {
let mut ans = 0;
let mut cnt: HashMap<i32, i32> = HashMap::new();
for s in words {
let mut x = 0;
for c in s.chars() {
x |= 1 << ((c as u8) - b'a');
}
ans += cnt.get(&x).unwrap_or(&0);
*cnt.entry(x).or_insert(0) += 1;
}
ans
}
}