本题解采用了回溯法来解决问题。首先,定义一个集合 `r` 来存储当前路径中的所有子字符串,保证它们的唯一性。`res` 变量用于记录最大的唯一子字符串数目。\n\n函数 `split(i)` 的参数 `i` 表示当前考虑的字符串的起始位置。如果 `i` 等于字符串的长度 `n`,说明已经检查完整个字符串,此时更新 `res` 的值。\n\n对于每个起始位置 `i`,循环尝试所有可能的结束位置 `j`。这里有一个剪枝操作:如果当前已有的唯一子字符串数加上剩余可能的最大子字符串数小于等于当前 `res`,则无需继续尝试,直接中断循环。如果从 `i` 到 `j` 的子字符串不在集合 `r` 中,则将其加入集合,递归地调用 `split(j)`,之后再将其从集合中移除,回溯到上一状态。
时间复杂度: O(2^n)
空间复杂度: O(n)
class Solution:
def maxUniqueSplit(self, s: str) -> int:
r = set() # 存储当前已生成的唯一子字符串集合
n = len(s) # 字符串的总长度
res = 0 # 最大唯一子字符串的数量
def split(i):
if i == n: # 如果已经处理完所有字符
nonlocal res
res = max(res, len(r)) # 更新最大唯一子字符串的数量
for j in range(i + 1, n + 1): # 尝试每一个可能的结束位置 j
if len(r) + 1 + n - j <= res: # 剪枝:如果当前组合的最大可能数量不会超过已知的最大数量,则停止尝试
break
if s[i:j] not in r: # 如果当前子字符串是唯一的
r.add(s[i: j]) # 添加到集合中
split(j) # 递归处理剩余字符串
r.remove(s[i: j]) # 回溯,移除当前子字符串,恢复状态
split(0)
return res # 返回最大唯一子字符串的数量