1593 拆分字符串使唯一子字符串的数目最大(递归)

该博客主要讨论了一道LeetCode题目,要求拆分给定字符串为最多数目的唯一子字符串。通过递归方法,尝试所有可能的字符串拆分组合,使用set集合记录并检查子字符串的唯一性。在递归过程中进行剪枝和回溯,以找到最大数量的唯一子字符串。代码中定义了一个名为`Solution`的类,包含`recursion`和`maxUniqueSplit`两个方法,分别用于递归拆分和返回结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 问题描述:

给你一个字符串 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 仅包含小写英文字母

来源:https://leetcode-cn.com/problems/split-a-string-into-the-max-number-of-unique-substrings/

2. 思路分析:

① 从题目中可以知道我们需要将字符串分解为若干个唯一的子字符串并且使得到的子字符串的数目是最大的,所以比较容易想到的是使用递归去尝试所有可能的字符串的拆分情况,比如从当前的索引开始,尝试截取1,2,3...k个字符(因为截取的字符串可能与之前的重复的所以必须要尝试不同的截取长度使得当前截取的字符串与之前的不同),并且从字符串的每一个位置开始截取的时候都可以这样尝试所以我们可以使用for循环进行递归,尝试从当前索引开始截取k个长度的字符串:

在for循环中递归截取字符串的时候需要考虑边界问题,因为字符串的长度最大为len(s),而当前的索引为index,所以截取的最大长度就为len(s) - index。

② 我们递归的时候需要使用set集合来记录中间截取的字符串,判断当前截取的字符串是否以之前截取的字符串发生重复,并且在递归方法调用之前需要将截取的字符串加入到set集合中,当递归方法结束之后需要将加入的最后一个字符串删除掉(回溯),这样才可以尝试for循环中的下一个可能截取的字符串。

③ 凡是事先不知道怎么样的划分或者组合才可以得到最佳的解决方案都是可以递归的方法尝试所有的可能的方法得到最佳结果的。

3. 代码如下:

import sys


class Solution:
    res = -sys.maxsize
    """
    @param index: 字符串截取的开始位置
    @param rec: 记录中间结果看判断是否存在重复的元素
    @return: 
    """
    def recursion(self, s: str, index: int, rec: set):
        # if的第一个判断条件是剪枝当发现递归的最终结果小于等于了之前的res那么直接return了
        if len(rec) + len(s) - index + 1 <= self.res or index == len(s):
            self.res = max(self.res, len(rec))
            return
        # 使用for循环尝试从当前索引index位置开始截取k个长度,需要注意边界为len(s) - index + 1
        for i in range(1, len(s) - index + 1):
            # s[index: index + i]为python中的切片操作
            if s[index: index + i] not in rec:
                rec.add(s[index: index + i])
                self.recursion(s, index + i, rec)
                # 回溯, 以便可以尝试其他字符串截取情况
                rec.remove(s[index: index + i])

    def maxUniqueSplit(self, s: str) -> int:
        self.recursion(s, 0, set())
        return self.res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值