Skip to content

feat: add solutions to lc problem: No.1593 #3889

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

Merged
merged 1 commit into from
Dec 26, 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 @@ -68,9 +68,17 @@ tags:

<!-- solution:start -->

### 方法一:DFS
### 方法一:回溯 + 剪枝

经典 DFS 回溯问题。
我们定义一个哈希表 $\textit{st}$,用于存储当前已经拆分出的子字符串。然后我们使用深度优先搜索的方式,尝试将字符串 $\textit{s}$ 拆分成若干个唯一的子字符串。

具体地,我们设计一个函数 $\text{dfs}(i)$,表示我们正在考虑将 $\textit{s}[i:]$ 进行拆分。

在函数 $\text{dfs}(i)$ 中,我们首先判断如果当前已经拆分出的子字符串的数量加上剩余的字符数小于等于当前的答案,那么我们就没有必要继续拆分,直接返回。如果 $i \geq n$,那么说明我们已经完成了对整个字符串的拆分,我们更新答案为当前的子字符串数量和答案的较大值。否则,我们枚举当前子字符串的结束位置 $j$(不包括 $j$),并判断 $\textit{s}[i..j)$ 是否已经被拆分出来。如果没有被拆分出来,我们将其加入到哈希表 $\textit{st}$ 中,并继续递归地考虑拆分剩余的部分。在递归调用结束后,我们需要将 $\textit{s}[i..j)$ 从哈希表 $\textit{st}$ 中移除。

最后,我们返回答案。

时间复杂度 $O(n^2 \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $\textit{s}$ 的长度。

<!-- tabs:start -->

Expand All @@ -79,47 +87,52 @@ tags:
```python
class Solution:
def maxUniqueSplit(self, s: str) -> int:
def dfs(i, t):
def dfs(i: int):
nonlocal ans
if len(st) + len(s) - i <= ans:
return
if i >= len(s):
nonlocal ans
ans = max(ans, t)
ans = max(ans, len(st))
return
for j in range(i + 1, len(s) + 1):
if s[i:j] not in vis:
vis.add(s[i:j])
dfs(j, t + 1)
vis.remove(s[i:j])

vis = set()
ans = 1
dfs(0, 0)
if s[i:j] not in st:
st.add(s[i:j])
dfs(j)
st.remove(s[i:j])

ans = 0
st = set()
dfs(0)
return ans
```

#### Java

```java
class Solution {
private Set<String> vis = new HashSet<>();
private int ans = 1;
private Set<String> st = new HashSet<>();
private int ans;
private String s;

public int maxUniqueSplit(String s) {
this.s = s;
dfs(0, 0);
dfs(0);
return ans;
}

private void dfs(int i, int t) {
private void dfs(int i) {
if (st.size() + s.length() - i <= ans) {
return;
}
if (i >= s.length()) {
ans = Math.max(ans, t);
ans = Math.max(ans, st.size());
return;
}
for (int j = i + 1; j <= s.length(); ++j) {
String x = s.substring(i, j);
if (vis.add(x)) {
dfs(j, t + 1);
vis.remove(x);
String t = s.substring(i, j);
if (st.add(t)) {
dfs(j);
st.remove(t);
}
}
}
Expand All @@ -131,57 +144,87 @@ class Solution {
```cpp
class Solution {
public:
unordered_set<string> vis;
string s;
int ans = 1;

int maxUniqueSplit(string s) {
this->s = s;
dfs(0, 0);
return ans;
}

void dfs(int i, int t) {
if (i >= s.size()) {
ans = max(ans, t);
return;
}
for (int j = i + 1; j <= s.size(); ++j) {
string x = s.substr(i, j - i);
if (!vis.count(x)) {
vis.insert(x);
dfs(j, t + 1);
vis.erase(x);
unordered_set<string> st;
int n = s.size();
int ans = 0;
auto dfs = [&](this auto&& dfs, int i) -> void {
if (st.size() + n - i <= ans) {
return;
}
}
if (i >= n) {
ans = max(ans, (int) st.size());
return;
}
for (int j = i + 1; j <= n; ++j) {
string t = s.substr(i, j - i);
if (!st.contains(t)) {
st.insert(t);
dfs(j);
st.erase(t);
}
}
};
dfs(0);
return ans;
}
};
```

#### Go

```go
func maxUniqueSplit(s string) int {
ans := 1
vis := map[string]bool{}

var dfs func(i, t int)
dfs = func(i, t int) {
if i >= len(s) {
ans = max(ans, t)
func maxUniqueSplit(s string) (ans int) {
st := map[string]bool{}
n := len(s)
var dfs func(int)
dfs = func(i int) {
if len(st)+n-i <= ans {
return
}
if i >= n {
ans = max(ans, len(st))
return
}
for j := i + 1; j <= len(s); j++ {
x := s[i:j]
if !vis[x] {
vis[x] = true
dfs(j, t+1)
vis[x] = false
for j := i + 1; j <= n; j++ {
if t := s[i:j]; !st[t] {
st[t] = true
dfs(j)
delete(st, t)
}
}
}
dfs(0, 0)
return ans
dfs(0)
return
}
```

#### TypeScript

```ts
function maxUniqueSplit(s: string): number {
const n = s.length;
const st = new Set<string>();
let ans = 0;
const dfs = (i: number): void => {
if (st.size + n - i <= ans) {
return;
}
if (i >= n) {
ans = Math.max(ans, st.size);
return;
}
for (let j = i + 1; j <= n; ++j) {
const t = s.slice(i, j);
if (!st.has(t)) {
st.add(t);
dfs(j);
st.delete(t);
}
}
};
dfs(0);
return ans;
}
```

Expand Down
Loading
Loading