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 cf2a9dd

Browse files
feat: add solutions to lc problem: No.1239 (doocs#3555)
No.1239.Maximum Length of a Concatenated String with Unique Characters
1 parent 42478e4 commit cf2a9dd

File tree

7 files changed

+310
-213
lines changed

7 files changed

+310
-213
lines changed

‎solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README.md‎

Lines changed: 107 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,17 @@ tags:
7575

7676
<!-- solution:start -->
7777

78-
### 方法一:位运算 + 状态压缩
78+
### 方法一:状态压缩 + 位运算
7979

80-
状态压缩,用一个 32ドル$ 位数记录字母的出现情况,`masks` 存储之前枚举的字符串
80+
由于题目要求子序列的字符不能重复,字符都是小写字母,因此,我们可以用一个长度为 26ドル$ 的二进制整数来表示一个子序列,其中第 $i$ 位为 1ドル$ 表示子序列中含有滴 $i$ 个字符,为 0ドル$ 表示不含有第 $i$ 个字符
8181

82-
时间复杂度 $O(2^n + L),ドル空间复杂度 $O(2^n)$。其中 $n$ 和 $L$ 分别是字符串数组的长度和字符串数组中字符串的长度之和。
82+
我们可以用一个数组 $s$ 来存储所有满足条件的子序列的状态,初始时 $s$ 中只有一个元素 0ドル$。
83+
84+
然后我们遍历数组 $\textit{arr},ドル对于每个字符串 $t,ドル我们用一个整数 $x$ 来表示 $t$ 的状态,然后我们遍历数组 $s,ドル对于每个状态 $y,ドル如果 $x$ 和 $y$ 之间没有相同的字符,那么我们将 $x$ 和 $y$ 的并集加入到 $s$ 中,并更新答案。
85+
86+
最后我们返回答案即可。
87+
88+
时间复杂度 $O(2^n + L),ドル空间复杂度 $O(2^n),ドル其中 $n$ 是字符串数组的长度,而 $L$ 是字符串数组中所有字符串的长度之和。
8389

8490
<!-- tabs:start -->
8591

@@ -88,52 +94,44 @@ tags:
8894
```python
8995
class Solution:
9096
def maxLength(self, arr: List[str]) -> int:
91-
ans = 0
92-
masks = [0]
93-
for s in arr:
94-
mask = 0
95-
for c in s:
96-
i = ord(c) - ord('a')
97-
if mask >> i & 1:
98-
mask = 0
97+
s = [0]
98+
for t in arr:
99+
x = 0
100+
for b in map(lambda c: ord(c) - 97, t):
101+
if x >> b & 1:
102+
x = 0
99103
break
100-
mask |= 1 << i
101-
if mask == 0:
102-
continue
103-
for m in masks:
104-
if m & mask == 0:
105-
masks.append(m | mask)
106-
ans = max(ans, (m | mask).bit_count())
107-
return ans
104+
x |= 1 << b
105+
if x:
106+
s.extend((x | y) for y in s if (x & y) == 0)
107+
return max(x.bit_count() for x in s)
108108
```
109109

110110
#### Java
111111

112112
```java
113113
class Solution {
114114
public int maxLength(List<String> arr) {
115+
List<Integer> s = new ArrayList<>();
116+
s.add(0);
115117
int ans = 0;
116-
List<Integer> masks = new ArrayList<>();
117-
masks.add(0);
118-
for (var s : arr) {
119-
int mask = 0;
120-
for (int i = 0; i < s.length(); ++i) {
121-
int j = s.charAt(i) - 'a';
122-
if (((mask >> j) & 1) == 1) {
123-
mask = 0;
118+
for (var t : arr) {
119+
int x = 0;
120+
for (char c : t.toCharArray()) {
121+
int b = c - 'a';
122+
if ((x >> b & 1) == 1) {
123+
x = 0;
124124
break;
125125
}
126-
mask |= 1 << j;
126+
x |= 1 << b;
127127
}
128-
if (mask == 0) {
129-
continue;
130-
}
131-
int n = masks.size();
132-
for (int i = 0; i < n; ++i) {
133-
int m = masks.get(i);
134-
if ((m & mask) == 0) {
135-
masks.add(m | mask);
136-
ans = Math.max(ans, Integer.bitCount(m | mask));
128+
if (x > 0) {
129+
for (int i = s.size() - 1; i >= 0; --i) {
130+
int y = s.get(i);
131+
if ((x & y) == 0) {
132+
s.add(x | y);
133+
ans = Math.max(ans, Integer.bitCount(x | y));
134+
}
137135
}
138136
}
139137
}
@@ -148,27 +146,25 @@ class Solution {
148146
class Solution {
149147
public:
150148
int maxLength(vector<string>& arr) {
149+
vector<int> s = {0};
151150
int ans = 0;
152-
vector<int> masks = {0};
153-
for (auto& s : arr) {
154-
int mask = 0;
155-
for (auto& c : s) {
156-
int i = c - 'a';
157-
if (mask >> i & 1) {
158-
mask = 0;
151+
for (const string& t : arr) {
152+
int x = 0;
153+
for (char c : t) {
154+
int b = c - 'a';
155+
if ((x >> b & 1) == 1) {
156+
x = 0;
159157
break;
160158
}
161-
mask |= 1 << i;
162-
}
163-
if (mask == 0) {
164-
continue;
159+
x |= 1 << b;
165160
}
166-
int n = masks.size();
167-
for (int i = 0; i < n; ++i) {
168-
int m = masks[i];
169-
if ((m & mask) == 0) {
170-
masks.push_back(m | mask);
171-
ans = max(ans, __builtin_popcount(m | mask));
161+
if (x > 0) {
162+
for (int i = s.size() - 1; i >= 0; --i) {
163+
int y = s[i];
164+
if ((x & y) == 0) {
165+
s.push_back(x | y);
166+
ans = max(ans, __builtin_popcount(x | y));
167+
}
172168
}
173169
}
174170
}
@@ -181,29 +177,69 @@ public:
181177
182178
```go
183179
func maxLength(arr []string) (ans int) {
184-
masks := []int{0}
185-
for _, s := range arr {
186-
mask := 0
187-
for _, c := range s {
188-
i := int(c - 'a')
189-
if mask>>i&1 == 1 {
190-
mask = 0
180+
s := []int{0}
181+
for _, t := range arr {
182+
x := 0
183+
for _, c := range t {
184+
b := int(c - 'a')
185+
if (x>>b)&1 == 1 {
186+
x = 0
191187
break
192188
}
193-
mask |= 1 << i
189+
x |= 1 << b
194190
}
195-
if mask == 0 {
196-
continue
197-
}
198-
n := len(masks)
199-
for _, m := range masks[:n] {
200-
if m&mask == 0 {
201-
masks = append(masks, m|mask)
202-
ans = max(ans, bits.OnesCount(uint(m|mask)))
191+
if x > 0 {
192+
for i := len(s) - 1; i >= 0; i-- {
193+
y := s[i]
194+
if (x & y) == 0 {
195+
s = append(s, x|y)
196+
ans = max(ans, bits.OnesCount(uint(x|y)))
197+
}
203198
}
204199
}
205200
}
206-
return
201+
return ans
202+
}
203+
```
204+
205+
#### TypeScript
206+
207+
```ts
208+
function maxLength(arr: string[]): number {
209+
const s: number[] = [0];
210+
let ans = 0;
211+
for (const t of arr) {
212+
let x = 0;
213+
for (const c of t) {
214+
const b = c.charCodeAt(0) - 97;
215+
if ((x >> b) & 1) {
216+
x = 0;
217+
break;
218+
}
219+
x |= 1 << b;
220+
}
221+
222+
if (x > 0) {
223+
for (let i = s.length - 1; ~i; --i) {
224+
const y = s[i];
225+
if ((x & y) === 0) {
226+
s.push(x | y);
227+
ans = Math.max(ans, bitCount(x | y));
228+
}
229+
}
230+
}
231+
}
232+
233+
return ans;
234+
}
235+
236+
function bitCount(i: number): number {
237+
i = i - ((i >>> 1) & 0x55555555);
238+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
239+
i = (i + (i >>> 4)) & 0x0f0f0f0f;
240+
i = i + (i >>> 8);
241+
i = i + (i >>> 16);
242+
return i & 0x3f;
207243
}
208244
```
209245

0 commit comments

Comments
(0)

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