Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1f0097d

Browse files
feat: add solutions to lc problem: No.0318 (#1932)
No.0318.Maximum Product of Word Lengths
1 parent 49a3619 commit 1f0097d

File tree

7 files changed

+402
-121
lines changed

7 files changed

+402
-121
lines changed

‎solution/0300-0399/0318.Maximum Product of Word Lengths/README.md‎

Lines changed: 166 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@
4646

4747
<!-- 这里可写通用的实现逻辑 -->
4848

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+
4959
<!-- tabs:start -->
5060

5161
### **Python3**
@@ -55,16 +65,31 @@
5565
```python
5666
class Solution:
5767
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)
6383
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)
6893
return ans
6994
```
7095

@@ -76,19 +101,41 @@ class Solution:
76101
class Solution {
77102
public int maxProduct(String[] words) {
78103
int n = words.length;
79-
int[] masks = new int[n];
104+
int[] mask = new int[n];
105+
int ans = 0;
80106
for (int i = 0; i < n; ++i) {
81107
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+
}
83114
}
84115
}
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<>();
85125
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);
90136
}
91137
}
138+
mask.merge(x, a, Math::max);
92139
}
93140
return ans;
94141
}
@@ -102,15 +149,43 @@ class Solution {
102149
public:
103150
int maxProduct(vector<string>& words) {
104151
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));
109154
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) {
113161
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+
}
114189
return ans;
115190
}
116191
};
@@ -119,23 +194,82 @@ public:
119194
### **Go**
120195

121196
```go
122-
func maxProduct(words []string) int {
197+
func maxProduct(words []string) (ansint) {
123198
n := len(words)
124199
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')
128203
}
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] {
133205
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)
135226
}
136227
}
228+
mask[x] = max(mask[x], a)
137229
}
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;
139273
}
140274
```
141275

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /