leetcode1593. 拆分字符串使唯一子字符串的数目最大
给你一个字符串 s
,请你拆分该字符串,并返回拆分后唯一子字符串的最大数目。
字符串 s
拆分后可以得到若干 非空子字符串 ,这些子字符串连接后应当能够还原为原字符串。但是拆分出来的每个子字符串都必须是 唯一的 。
注意:子字符串 是字符串中的一个连续字符序列。
示例 1:
输入:s = "ababccc"
输出:5
解释:一种最大拆分方法为 ['a', 'b', 'ab', 'c', 'cc'] 。像 ['a', 'b', 'a', 'b', 'c', 'cc'] 这样拆分不满足题目要求,因为其中的 'a' 和 'b' 都出现了不止一次。
示例 2:
输入:s = "aba"
输出:2
解释:一种最大拆分方法为 ['a', 'ba'] 。
示例 3:
输入:s = "aa"
输出:1
解释:无法进一步拆分字符串。
提示:
1 <= s.length <= 16
s
仅包含小写英文字母
方法:dfs回溯+剪枝
思路:
首先我们查看数据范围,s的长度最长只有16,那么说明我们的dfs回溯的方法应该是可以解决的。
我们维护一个集合,保存我们拆分好的不同的字符串。
我们对每个下标位置进行dfs,对于下标idx,我们可以选择的以s[idx]为字符串开头的拆分方式有n-idx种。即只有一个字符s[idx]、s[idx]和之后的一个字符、s[idx]和之后的两个字符…直到从idx开始一直到s结尾。
我们假设将s[idx,i](闭区间)作为新的拆分放入集合中(如果该字符串不在集合中),如果在集合中,那么我们直接跳过,剪枝。那么下一步的dfs即为dfs(i+1)。
我们递归的结束条件应该是i==n
,n为s的长度。
另外,我们还可以进行另一种剪枝,来减少计算量,**我们遍历到idx的时候,剩下的字符串最多可以分为n-idx种,即每个字符都是不同的情况,我们使用ans维护的当前的答案,那么如果n-idx+len(words)<=ans
,**即最大情况下也比目前的ans小,那么我们可以直接剪枝。
代码:
Python3:
class Solution:
def maxUniqueSplit(self, s: str) -> int: