46
46
47
47
<!-- 这里可写通用的实现逻辑 -->
48
48
49
+ ** 方法一:位运算**
50
+
51
+ 题目需要我们找到两个没有公共字母的字符串,使得它们的长度乘积最大。我们可以将每个字符串用一个二进制数 $mask[ i] $ 表示,这个二进制数的每一位表示字符串中是否含有某个字母。如果两个字符串没有公共字母,那么这两个字符串对应的二进制数的按位与的结果为 $0$,即 $mask[ i] \& mask[ j] = 0$。
52
+
53
+ 我们遍历每个字符串,对于当前遍历到的字符串 $words[ i] $,我们先算出对应的二进制数 $mask[ i] $,然后再遍历 $j \in [ 0, i)$ 的所有字符串 $words[ j] $,检查 $mask[ i] \& mask[ j] = 0$ 是否成立,如果成立就更新答案为 $\max(ans, |words[ i] | \times |words[ j] |)$。
54
+
55
+ 遍历结束后,返回答案即可。
56
+
57
+ 时间复杂度 $O(n^2 + L)$,空间复杂度 $O(n)$。其中 $n$ 是字符串数组 $words$ 的长度,而 $L$ 是字符串数组所有字符串的长度之和。
58
+
49
59
<!-- tabs:start -->
50
60
51
61
### ** Python3**
55
65
``` python
56
66
class Solution :
57
67
def maxProduct (self , words : List[str ]) -> int :
58
- n = len (words)
59
- mask = [0 ] * n
60
- for i, word in enumerate (words):
61
- for ch in word:
62
- mask[i] |= 1 << (ord (ch) - ord (' a' ))
68
+ mask = [0 ] * len (words)
69
+ ans = 0
70
+ for i, s in enumerate (words):
71
+ for c in s:
72
+ mask[i] |= 1 << (ord (c) - ord (" a" ))
73
+ for j, t in enumerate (words[:i]):
74
+ if (mask[i] & mask[j]) == 0 :
75
+ ans = max (ans, len (s) * len (t))
76
+ return ans
77
+ ```
78
+
79
+ ``` python
80
+ class Solution :
81
+ def maxProduct (self , words : List[str ]) -> int :
82
+ mask = defaultdict(int )
63
83
ans = 0
64
- for i in range (n - 1 ):
65
- for j in range (i + 1 , n):
66
- if mask[i] & mask[j] == 0 :
67
- ans = max (ans, len (words[i]) * len (words[j]))
84
+ for s in words:
85
+ a = len (s)
86
+ x = 0
87
+ for c in s:
88
+ x |= 1 << (ord (c) - ord (" a" ))
89
+ for y, b in mask.items():
90
+ if (x & y) == 0 :
91
+ ans = max (ans, a * b)
92
+ mask[x] = max (mask[x], a)
68
93
return ans
69
94
```
70
95
@@ -76,19 +101,41 @@ class Solution:
76
101
class Solution {
77
102
public int maxProduct (String [] words ) {
78
103
int n = words. length;
79
- int [] masks = new int [n];
104
+ int [] mask = new int [n];
105
+ int ans = 0 ;
80
106
for (int i = 0 ; i < n; ++ i) {
81
107
for (char c : words[i]. toCharArray()) {
82
- masks[i] |= (1 << (c - ' a' ));
108
+ mask[i] |= 1 << (c - ' a' );
109
+ }
110
+ for (int j = 0 ; j < i; ++ j) {
111
+ if ((mask[i] & mask[j]) == 0 ) {
112
+ ans = Math . max(ans, words[i]. length() * words[j]. length());
113
+ }
83
114
}
84
115
}
116
+ return ans;
117
+ }
118
+ }
119
+ ```
120
+
121
+ ``` java
122
+ class Solution {
123
+ public int maxProduct (String [] words ) {
124
+ Map<Integer , Integer > mask = new HashMap<> ();
85
125
int ans = 0 ;
86
- for (int i = 0 ; i < n - 1 ; ++ i) {
87
- for (int j = i + 1 ; j < n; ++ j) {
88
- if ((masks[i] & masks[j]) == 0 ) {
89
- ans = Math . max(ans, words[i]. length() * words[j]. length());
126
+ for (var s : words) {
127
+ int a = s. length();
128
+ int x = 0 ;
129
+ for (char c : s. toCharArray()) {
130
+ x |= 1 << (c - ' a' );
131
+ }
132
+ for (var e : mask. entrySet()) {
133
+ int y = e. getKey(), b = e. getValue();
134
+ if ((x & y) == 0 ) {
135
+ ans = Math . max(ans, a * b);
90
136
}
91
137
}
138
+ mask. merge(x, a, Math :: max);
92
139
}
93
140
return ans;
94
141
}
@@ -102,15 +149,43 @@ class Solution {
102
149
public:
103
150
int maxProduct(vector<string >& words) {
104
151
int n = words.size();
105
- vector<int > mask(n);
106
- for (int i = 0; i < n; ++i)
107
- for (char ch : words[ i] )
108
- mask[ i] |= 1 << (ch - 'a');
152
+ int mask[ n] ;
153
+ memset(mask, 0, sizeof(mask));
109
154
int ans = 0;
110
- for (int i = 0; i < n - 1; ++i)
111
- for (int j = i + 1; j < n; ++j)
112
- if (!(mask[ i] & mask[ j] ))
155
+ for (int i = 0; i < n; ++i) {
156
+ for (char& c : words[ i] ) {
157
+ mask[ i] |= 1 << (c - 'a');
158
+ }
159
+ for (int j = 0; j < i; ++j) {
160
+ if ((mask[ i] & mask[ j] ) == 0) {
113
161
ans = max(ans, (int) (words[ i] .size() * words[ j] .size()));
162
+ }
163
+ }
164
+ }
165
+ return ans;
166
+ }
167
+ };
168
+ ```
169
+
170
+ ```cpp
171
+ class Solution {
172
+ public:
173
+ int maxProduct(vector<string>& words) {
174
+ unordered_map<int, int> mask;
175
+ int ans = 0;
176
+ for (auto& s : words) {
177
+ int a = s.size();
178
+ int x = 0;
179
+ for (char& c : s) {
180
+ x |= 1 << (c - 'a');
181
+ }
182
+ for (auto& [y, b] : mask) {
183
+ if ((x & y) == 0) {
184
+ ans = max(ans, a * b);
185
+ }
186
+ }
187
+ mask[x] = max(mask[x], a);
188
+ }
114
189
return ans;
115
190
}
116
191
};
@@ -119,23 +194,82 @@ public:
119
194
### ** Go**
120
195
121
196
``` go
122
- func maxProduct(words []string) int {
197
+ func maxProduct (words []string ) ( ans int ) {
123
198
n := len (words)
124
199
mask := make ([]int , n)
125
- for i, word := range words {
126
- for _, c := range word {
127
- mask[i] |= ( 1 << (c - 'a') )
200
+ for i , s := range words {
201
+ for _ , c := range s {
202
+ mask[i] |= 1 << (c - ' a' )
128
203
}
129
- }
130
- ans := 0
131
- for i := 0; i < n-1; i++ {
132
- for j := i + 1; j < n; j++ {
204
+ for j , t := range words[:i] {
133
205
if mask[i]&mask[j] == 0 {
134
- ans = max(ans, len(words[i])*len(words[j]))
206
+ ans = max (ans, len (s)*len (t))
207
+ }
208
+ }
209
+ }
210
+ return
211
+ }
212
+ ```
213
+
214
+ ``` go
215
+ func maxProduct (words []string ) (ans int ) {
216
+ mask := map [int ]int {}
217
+ for _ , s := range words {
218
+ a := len (s)
219
+ x := 0
220
+ for _ , c := range s {
221
+ x |= 1 << (c - ' a' )
222
+ }
223
+ for y , b := range mask {
224
+ if x&y == 0 {
225
+ ans = max (ans, a*b)
135
226
}
136
227
}
228
+ mask[x] = max (mask[x], a)
137
229
}
138
- return ans
230
+ return
231
+ }
232
+ ```
233
+
234
+ ### ** TypeScript**
235
+
236
+ ``` ts
237
+ function maxProduct(words : string []): number {
238
+ const n = words .length ;
239
+ const mask: number [] = Array (n ).fill (0 );
240
+ let ans = 0 ;
241
+ for (let i = 0 ; i < n ; ++ i ) {
242
+ for (const c of words [i ]) {
243
+ mask [i ] |= 1 << (c .charCodeAt (0 ) - ' a' .charCodeAt (0 ));
244
+ }
245
+ for (let j = 0 ; j < i ; ++ j ) {
246
+ if ((mask [i ] & mask [j ]) === 0 ) {
247
+ ans = Math .max (ans , words [i ].length * words [j ].length );
248
+ }
249
+ }
250
+ }
251
+ return ans ;
252
+ }
253
+ ```
254
+
255
+ ``` ts
256
+ function maxProduct(words : string []): number {
257
+ const mask: Map <number , number > = new Map ();
258
+ let ans = 0 ;
259
+ for (const s of words ) {
260
+ const a = s .length ;
261
+ let x = 0 ;
262
+ for (const c of s ) {
263
+ x |= 1 << (c .charCodeAt (0 ) - ' a' .charCodeAt (0 ));
264
+ }
265
+ for (const [y, b] of mask .entries ()) {
266
+ if ((x & y ) === 0 ) {
267
+ ans = Math .max (ans , a * b );
268
+ }
269
+ }
270
+ mask .set (x , Math .max (mask .get (x ) || 0 , a ));
271
+ }
272
+ return ans ;
139
273
}
140
274
```
141
275
0 commit comments