Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.1239 #3555

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,17 @@ tags:

<!-- solution:start -->

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

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

时间复杂度 $O(2^n + L)$,空间复杂度 $O(2^n)$。其中 $n$ 和 $L$ 分别是字符串数组的长度和字符串数组中字符串的长度之和。
我们可以用一个数组 $s$ 来存储所有满足条件的子序列的状态,初始时 $s$ 中只有一个元素 $0$。

然后我们遍历数组 $\textit{arr}$,对于每个字符串 $t$,我们用一个整数 $x$ 来表示 $t$ 的状态,然后我们遍历数组 $s$,对于每个状态 $y$,如果 $x$ 和 $y$ 之间没有相同的字符,那么我们将 $x$ 和 $y$ 的并集加入到 $s$ 中,并更新答案。

最后我们返回答案即可。

时间复杂度 $O(2^n + L)$,空间复杂度 $O(2^n)$,其中 $n$ 是字符串数组的长度,而 $L$ 是字符串数组中所有字符串的长度之和。

<!-- tabs:start -->

Expand All @@ -88,52 +94,44 @@ tags:
```python
class Solution:
def maxLength(self, arr: List[str]) -> int:
ans = 0
masks = [0]
for s in arr:
mask = 0
for c in s:
i = ord(c) - ord('a')
if mask >> i & 1:
mask = 0
s = [0]
for t in arr:
x = 0
for b in map(lambda c: ord(c) - 97, t):
if x >> b & 1:
x = 0
break
mask |= 1 << i
if mask == 0:
continue
for m in masks:
if m & mask == 0:
masks.append(m | mask)
ans = max(ans, (m | mask).bit_count())
return ans
x |= 1 << b
if x:
s.extend((x | y) for y in s if (x & y) == 0)
return max(x.bit_count() for x in s)
```

#### Java

```java
class Solution {
public int maxLength(List<String> arr) {
List<Integer> s = new ArrayList<>();
s.add(0);
int ans = 0;
List<Integer> masks = new ArrayList<>();
masks.add(0);
for (var s : arr) {
int mask = 0;
for (int i = 0; i < s.length(); ++i) {
int j = s.charAt(i) - 'a';
if (((mask >> j) & 1) == 1) {
mask = 0;
for (var t : arr) {
int x = 0;
for (char c : t.toCharArray()) {
int b = c - 'a';
if ((x >> b & 1) == 1) {
x = 0;
break;
}
mask |= 1 << j;
x |= 1 << b;
}
if (mask == 0) {
continue;
}
int n = masks.size();
for (int i = 0; i < n; ++i) {
int m = masks.get(i);
if ((m & mask) == 0) {
masks.add(m | mask);
ans = Math.max(ans, Integer.bitCount(m | mask));
if (x > 0) {
for (int i = s.size() - 1; i >= 0; --i) {
int y = s.get(i);
if ((x & y) == 0) {
s.add(x | y);
ans = Math.max(ans, Integer.bitCount(x | y));
}
}
}
}
Expand All @@ -148,27 +146,25 @@ class Solution {
class Solution {
public:
int maxLength(vector<string>& arr) {
vector<int> s = {0};
int ans = 0;
vector<int> masks = {0};
for (auto& s : arr) {
int mask = 0;
for (auto& c : s) {
int i = c - 'a';
if (mask >> i & 1) {
mask = 0;
for (const string& t : arr) {
int x = 0;
for (char c : t) {
int b = c - 'a';
if ((x >> b & 1) == 1) {
x = 0;
break;
}
mask |= 1 << i;
}
if (mask == 0) {
continue;
x |= 1 << b;
}
int n = masks.size();
for (int i = 0; i < n; ++i) {
int m = masks[i];
if ((m & mask) == 0) {
masks.push_back(m | mask);
ans = max(ans, __builtin_popcount(m | mask));
if (x > 0) {
for (int i = s.size() - 1; i >= 0; --i) {
int y = s[i];
if ((x & y) == 0) {
s.push_back(x | y);
ans = max(ans, __builtin_popcount(x | y));
}
}
}
}
Expand All @@ -181,29 +177,69 @@ public:

```go
func maxLength(arr []string) (ans int) {
masks := []int{0}
for _, s := range arr {
mask := 0
for _, c := range s {
i := int(c - 'a')
if mask>>i&1 == 1 {
mask = 0
s := []int{0}
for _, t := range arr {
x := 0
for _, c := range t {
b := int(c - 'a')
if (x>>b)&1 == 1 {
x = 0
break
}
mask |= 1 << i
x |= 1 << b
}
if mask == 0 {
continue
}
n := len(masks)
for _, m := range masks[:n] {
if m&mask == 0 {
masks = append(masks, m|mask)
ans = max(ans, bits.OnesCount(uint(m|mask)))
if x > 0 {
for i := len(s) - 1; i >= 0; i-- {
y := s[i]
if (x & y) == 0 {
s = append(s, x|y)
ans = max(ans, bits.OnesCount(uint(x|y)))
}
}
}
}
return
return ans
}
```

#### TypeScript

```ts
function maxLength(arr: string[]): number {
const s: number[] = [0];
let ans = 0;
for (const t of arr) {
let x = 0;
for (const c of t) {
const b = c.charCodeAt(0) - 97;
if ((x >> b) & 1) {
x = 0;
break;
}
x |= 1 << b;
}

if (x > 0) {
for (let i = s.length - 1; ~i; --i) {
const y = s[i];
if ((x & y) === 0) {
s.push(x | y);
ans = Math.max(ans, bitCount(x | y));
}
}
}
}

return ans;
}

function bitCount(i: number): number {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
```

Expand Down
Loading
Loading