Skip to content

Commit e7d8237

Browse files
authored
feat: add solutions to lc problem: No.2506 (doocs#3493)
1 parent 83ea32e commit e7d8237

File tree

8 files changed

+132
-135
lines changed

8 files changed

+132
-135
lines changed

solution/2500-2599/2506.Count Pairs Of Similar Strings/README.md

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ tags:
4141
<strong>输入:</strong>words = ["aba","aabb","abcd","bac","aabc"]
4242
<strong>输出:</strong>2
4343
<strong>解释:</strong>共有 2 对满足条件:
44-
- i = 0 且 j = 1 :words[0] 和 words[1] 只由字符 'a' 和 'b' 组成。
45-
- i = 3 且 j = 4 :words[3] 和 words[4] 只由字符 'a'、'b' 和 'c' 。
44+
- i = 0 且 j = 1 :words[0] 和 words[1] 只由字符 'a' 和 'b' 组成。
45+
- i = 3 且 j = 4 :words[3] 和 words[4] 只由字符 'a'、'b' 和 'c' 。
4646
</pre>
4747

4848
<p><strong>示例 2:</strong></p>
@@ -51,9 +51,9 @@ tags:
5151
<strong>输入:</strong>words = ["aabb","ab","ba"]
5252
<strong>输出:</strong>3
5353
<strong>解释:</strong>共有 3 对满足条件:
54-
- i = 0 且 j = 1 :words[0] 和 words[1] 只由字符 'a' 和 'b' 组成。
55-
- i = 0 且 j = 2 :words[0] 和 words[2] 只由字符 'a' 和 'b' 组成。
56-
- i = 1 且 j = 2 :words[1] 和 words[2] 只由字符 'a' 和 'b' 组成。
54+
- i = 0 且 j = 1 :words[0] 和 words[1] 只由字符 'a' 和 'b' 组成。
55+
- i = 0 且 j = 2 :words[0] 和 words[2] 只由字符 'a' 和 'b' 组成。
56+
- i = 1 且 j = 2 :words[1] 和 words[2] 只由字符 'a' 和 'b' 组成。
5757
</pre>
5858

5959
<p><strong>示例 3:</strong></p>
@@ -96,12 +96,12 @@ class Solution:
9696
def similarPairs(self, words: List[str]) -> int:
9797
ans = 0
9898
cnt = Counter()
99-
for w in words:
100-
v = 0
101-
for c in w:
102-
v |= 1 << (ord(c) - ord("A"))
103-
ans += cnt[v]
104-
cnt[v] += 1
99+
for s in words:
100+
x = 0
101+
for c in map(ord, s):
102+
x |= 1 << (c - ord("a"))
103+
ans += cnt[x]
104+
cnt[x] += 1
105105
return ans
106106
```
107107

@@ -112,13 +112,13 @@ class Solution {
112112
public int similarPairs(String[] words) {
113113
int ans = 0;
114114
Map<Integer, Integer> cnt = new HashMap<>();
115-
for (var w : words) {
116-
int v = 0;
117-
for (int i = 0; i < w.length(); ++i) {
118-
v |= 1 << (w.charAt(i) - 'a');
115+
for (var s : words) {
116+
int x = 0;
117+
for (char c : s.toCharArray()) {
118+
x |= 1 << (c - 'a');
119119
}
120-
ans += cnt.getOrDefault(v, 0);
121-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
120+
ans += cnt.getOrDefault(x, 0);
121+
cnt.merge(x, 1, Integer::sum);
122122
}
123123
return ans;
124124
}
@@ -133,11 +133,12 @@ public:
133133
int similarPairs(vector<string>& words) {
134134
int ans = 0;
135135
unordered_map<int, int> cnt;
136-
for (auto& w : words) {
137-
int v = 0;
138-
for (auto& c : w) v |= 1 << c - 'a';
139-
ans += cnt[v];
140-
cnt[v]++;
136+
for (const auto& s : words) {
137+
int x = 0;
138+
for (auto& c : s) {
139+
x |= 1 << (c - 'a');
140+
}
141+
ans += cnt[x]++;
141142
}
142143
return ans;
143144
}
@@ -149,13 +150,13 @@ public:
149150
```go
150151
func similarPairs(words []string) (ans int) {
151152
cnt := map[int]int{}
152-
for _, w := range words {
153-
v := 0
154-
for _, c := range w {
155-
v |= 1 << (c - 'a')
153+
for _, s := range words {
154+
x := 0
155+
for _, c := range s {
156+
x |= 1 << (c - 'a')
156157
}
157-
ans += cnt[v]
158-
cnt[v]++
158+
ans += cnt[x]
159+
cnt[x]++
159160
}
160161
return
161162
}
@@ -166,14 +167,14 @@ func similarPairs(words []string) (ans int) {
166167
```ts
167168
function similarPairs(words: string[]): number {
168169
let ans = 0;
169-
const cnt: Map<number, number> = new Map();
170-
for (const w of words) {
171-
let v = 0;
172-
for (let i = 0; i < w.length; ++i) {
173-
v |= 1 << (w.charCodeAt(i) - 'a'.charCodeAt(0));
170+
const cnt = new Map<number, number>();
171+
for (const s of words) {
172+
let x = 0;
173+
for (const c of s) {
174+
x |= 1 << (c.charCodeAt(0) - 97);
174175
}
175-
ans += cnt.get(v) || 0;
176-
cnt.set(v, (cnt.get(v) || 0) + 1);
176+
ans += cnt.get(x) || 0;
177+
cnt.set(x, (cnt.get(x) || 0) + 1);
177178
}
178179
return ans;
179180
}
@@ -187,19 +188,15 @@ use std::collections::HashMap;
187188
impl Solution {
188189
pub fn similar_pairs(words: Vec<String>) -> i32 {
189190
let mut ans = 0;
190-
let mut hash: HashMap<i32, i32> = HashMap::new();
191-
192-
for w in words {
193-
let mut v = 0;
194-
195-
for c in w.chars() {
196-
v |= 1 << ((c as u8) - b'a');
191+
let mut cnt: HashMap<i32, i32> = HashMap::new();
192+
for s in words {
193+
let mut x = 0;
194+
for c in s.chars() {
195+
x |= 1 << ((c as u8) - b'a');
197196
}
198-
199-
ans += hash.get(&v).unwrap_or(&0);
200-
*hash.entry(v).or_insert(0) += 1;
197+
ans += cnt.get(&x).unwrap_or(&0);
198+
*cnt.entry(x).or_insert(0) += 1;
201199
}
202-
203200
ans
204201
}
205202
}

solution/2500-2599/2506.Count Pairs Of Similar Strings/README_EN.md

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ tags:
4040
<strong>Input:</strong> words = [&quot;aba&quot;,&quot;aabb&quot;,&quot;abcd&quot;,&quot;bac&quot;,&quot;aabc&quot;]
4141
<strong>Output:</strong> 2
4242
<strong>Explanation:</strong> There are 2 pairs that satisfy the conditions:
43-
- i = 0 and j = 1 : both words[0] and words[1] only consist of characters &#39;a&#39; and &#39;b&#39;.
44-
- i = 3 and j = 4 : both words[3] and words[4] only consist of characters &#39;a&#39;, &#39;b&#39;, and &#39;c&#39;.
43+
- i = 0 and j = 1 : both words[0] and words[1] only consist of characters &#39;a&#39; and &#39;b&#39;.
44+
- i = 3 and j = 4 : both words[3] and words[4] only consist of characters &#39;a&#39;, &#39;b&#39;, and &#39;c&#39;.
4545
</pre>
4646

4747
<p><strong class="example">Example 2:</strong></p>
@@ -50,7 +50,7 @@ tags:
5050
<strong>Input:</strong> words = [&quot;aabb&quot;,&quot;ab&quot;,&quot;ba&quot;]
5151
<strong>Output:</strong> 3
5252
<strong>Explanation:</strong> There are 3 pairs that satisfy the conditions:
53-
- i = 0 and j = 1 : both words[0] and words[1] only consist of characters &#39;a&#39; and &#39;b&#39;.
53+
- i = 0 and j = 1 : both words[0] and words[1] only consist of characters &#39;a&#39; and &#39;b&#39;.
5454
- i = 0 and j = 2 : both words[0] and words[2] only consist of characters &#39;a&#39; and &#39;b&#39;.
5555
- i = 1 and j = 2 : both words[1] and words[2] only consist of characters &#39;a&#39; and &#39;b&#39;.
5656
</pre>
@@ -77,7 +77,13 @@ tags:
7777

7878
<!-- solution:start -->
7979

80-
### Solution 1
80+
### Solution 1: Hash Table + Bit Manipulation
81+
82+
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.
83+
84+
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$.
85+
86+
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.
8187

8288
<!-- tabs:start -->
8389

@@ -88,12 +94,12 @@ class Solution:
8894
def similarPairs(self, words: List[str]) -> int:
8995
ans = 0
9096
cnt = Counter()
91-
for w in words:
92-
v = 0
93-
for c in w:
94-
v |= 1 << (ord(c) - ord("A"))
95-
ans += cnt[v]
96-
cnt[v] += 1
97+
for s in words:
98+
x = 0
99+
for c in map(ord, s):
100+
x |= 1 << (c - ord("a"))
101+
ans += cnt[x]
102+
cnt[x] += 1
97103
return ans
98104
```
99105

@@ -104,13 +110,13 @@ class Solution {
104110
public int similarPairs(String[] words) {
105111
int ans = 0;
106112
Map<Integer, Integer> cnt = new HashMap<>();
107-
for (var w : words) {
108-
int v = 0;
109-
for (int i = 0; i < w.length(); ++i) {
110-
v |= 1 << (w.charAt(i) - 'a');
113+
for (var s : words) {
114+
int x = 0;
115+
for (char c : s.toCharArray()) {
116+
x |= 1 << (c - 'a');
111117
}
112-
ans += cnt.getOrDefault(v, 0);
113-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
118+
ans += cnt.getOrDefault(x, 0);
119+
cnt.merge(x, 1, Integer::sum);
114120
}
115121
return ans;
116122
}
@@ -125,11 +131,12 @@ public:
125131
int similarPairs(vector<string>& words) {
126132
int ans = 0;
127133
unordered_map<int, int> cnt;
128-
for (auto& w : words) {
129-
int v = 0;
130-
for (auto& c : w) v |= 1 << c - 'a';
131-
ans += cnt[v];
132-
cnt[v]++;
134+
for (const auto& s : words) {
135+
int x = 0;
136+
for (auto& c : s) {
137+
x |= 1 << (c - 'a');
138+
}
139+
ans += cnt[x]++;
133140
}
134141
return ans;
135142
}
@@ -141,13 +148,13 @@ public:
141148
```go
142149
func similarPairs(words []string) (ans int) {
143150
cnt := map[int]int{}
144-
for _, w := range words {
145-
v := 0
146-
for _, c := range w {
147-
v |= 1 << (c - 'a')
151+
for _, s := range words {
152+
x := 0
153+
for _, c := range s {
154+
x |= 1 << (c - 'a')
148155
}
149-
ans += cnt[v]
150-
cnt[v]++
156+
ans += cnt[x]
157+
cnt[x]++
151158
}
152159
return
153160
}
@@ -158,14 +165,14 @@ func similarPairs(words []string) (ans int) {
158165
```ts
159166
function similarPairs(words: string[]): number {
160167
let ans = 0;
161-
const cnt: Map<number, number> = new Map();
162-
for (const w of words) {
163-
let v = 0;
164-
for (let i = 0; i < w.length; ++i) {
165-
v |= 1 << (w.charCodeAt(i) - 'a'.charCodeAt(0));
168+
const cnt = new Map<number, number>();
169+
for (const s of words) {
170+
let x = 0;
171+
for (const c of s) {
172+
x |= 1 << (c.charCodeAt(0) - 97);
166173
}
167-
ans += cnt.get(v) || 0;
168-
cnt.set(v, (cnt.get(v) || 0) + 1);
174+
ans += cnt.get(x) || 0;
175+
cnt.set(x, (cnt.get(x) || 0) + 1);
169176
}
170177
return ans;
171178
}
@@ -179,19 +186,15 @@ use std::collections::HashMap;
179186
impl Solution {
180187
pub fn similar_pairs(words: Vec<String>) -> i32 {
181188
let mut ans = 0;
182-
let mut hash: HashMap<i32, i32> = HashMap::new();
183-
184-
for w in words {
185-
let mut v = 0;
186-
187-
for c in w.chars() {
188-
v |= 1 << ((c as u8) - b'a');
189+
let mut cnt: HashMap<i32, i32> = HashMap::new();
190+
for s in words {
191+
let mut x = 0;
192+
for c in s.chars() {
193+
x |= 1 << ((c as u8) - b'a');
189194
}
190-
191-
ans += hash.get(&v).unwrap_or(&0);
192-
*hash.entry(v).or_insert(0) += 1;
195+
ans += cnt.get(&x).unwrap_or(&0);
196+
*cnt.entry(x).or_insert(0) += 1;
193197
}
194-
195198
ans
196199
}
197200
}

solution/2500-2599/2506.Count Pairs Of Similar Strings/Solution.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ class Solution {
33
int similarPairs(vector<string>& words) {
44
int ans = 0;
55
unordered_map<int, int> cnt;
6-
for (auto& w : words) {
7-
int v = 0;
8-
for (auto& c : w) v |= 1 << c - 'a';
9-
ans += cnt[v];
10-
cnt[v]++;
6+
for (const auto& s : words) {
7+
int x = 0;
8+
for (auto& c : s) {
9+
x |= 1 << (c - 'a');
10+
}
11+
ans += cnt[x]++;
1112
}
1213
return ans;
1314
}
14-
};
15+
};
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
func similarPairs(words []string) (ans int) {
22
cnt := map[int]int{}
3-
for _, w := range words {
4-
v := 0
5-
for _, c := range w {
6-
v |= 1 << (c - 'a')
3+
for _, s := range words {
4+
x := 0
5+
for _, c := range s {
6+
x |= 1 << (c - 'a')
77
}
8-
ans += cnt[v]
9-
cnt[v]++
8+
ans += cnt[x]
9+
cnt[x]++
1010
}
1111
return
12-
}
12+
}

solution/2500-2599/2506.Count Pairs Of Similar Strings/Solution.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ class Solution {
22
public int similarPairs(String[] words) {
33
int ans = 0;
44
Map<Integer, Integer> cnt = new HashMap<>();
5-
for (var w : words) {
6-
int v = 0;
7-
for (int i = 0; i < w.length(); ++i) {
8-
v |= 1 << (w.charAt(i) - 'a');
5+
for (var s : words) {
6+
int x = 0;
7+
for (char c : s.toCharArray()) {
8+
x |= 1 << (c - 'a');
99
}
10-
ans += cnt.getOrDefault(v, 0);
11-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
10+
ans += cnt.getOrDefault(x, 0);
11+
cnt.merge(x, 1, Integer::sum);
1212
}
1313
return ans;
1414
}
15-
}
15+
}

solution/2500-2599/2506.Count Pairs Of Similar Strings/Solution.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ class Solution:
22
def similarPairs(self, words: List[str]) -> int:
33
ans = 0
44
cnt = Counter()
5-
for w in words:
6-
v = 0
7-
for c in w:
8-
v |= 1 << (ord(c) - ord("A"))
9-
ans += cnt[v]
10-
cnt[v] += 1
5+
for s in words:
6+
x = 0
7+
for c in map(ord, s):
8+
x |= 1 << (c - ord("a"))
9+
ans += cnt[x]
10+
cnt[x] += 1
1111
return ans

0 commit comments

Comments
 (0)