将字符串拆分为递减的连续值-LeetCode
1849. 将字符串拆分为递减的连续值
🎯 问题描述(来源于LeetCode)
描述:
给定一个字符串 s,判断是否能将其拆分成一个或多个连续递减 1 的整数序列(至少两个整数)。
每个子串表示一个整数,且不能有前导零(除非整数本身就是 0)。
拆分时必须使用所有字符,子串顺序不变。
说明:
- 数字序列应为
k, k-1, k-2, ...的形式。 - 例如
"1234"可以拆成[1,2,3,4],但这里要求递减,所以"4321"可以拆成[4,3,2,1]。 - 注意:0 的特殊性,例如
"1001"可以拆成[10,0,1]?这里不连续,所以不行。
示例:
- 示例 1:
1 | 输入: s = "1234" |
- 示例 2:
1 | 输入: s = "050043" |
- 示例 3:
1 | 输入: s = "9080701" |
💻 解题思路
思路:回溯法(DFS)尝试切分
算法步骤
- 获取字符串长度
n,初始化栈stack用于存储已确定的数字。 - 定义递归函数
dfs(i, cur),其中i表示当前处理到的下标,cur表示当前正在累积的子串(尚未切分):- 如果
i == n(已经遍历完所有字符):- 如果
cur非空(表示还有最后一段未切分),则将其转为数字num。- 若栈为空(说明只有一段),返回
False。 - 否则检查
num == stack[-1] - 1,若是则返回True,否则False。
- 若栈为空(说明只有一段),返回
- 如果
cur为空(说明已经切分到最后),则返回len(stack) >= 2(至少两个数字)。
- 如果
- 否则,分两种情况:
- 不切分:将当前字符追加到
cur,递归dfs(i+1, cur + s[i]),如果返回True则直接返回。 - 切分:如果
cur非空(即当前累积了一段子串),则将其转为整数num:- 如果栈为空,则将
num入栈,递归dfs(i+1, s[i]),然后回溯出栈。 - 如果栈非空,检查
num == stack[-1] - 1,若满足则入栈并递归,否则不进行切分。 - 递归返回
True则直接返回。
- 如果栈为空,则将
- 不切分:将当前字符追加到
- 若所有分支均失败,返回
False。
- 如果
- 从
dfs(0, "")开始搜索。 - 返回最终结果。
代码实现
1 | from typing import List |
📊 性能分析
- 时间复杂度:最坏情况下 ,每个字符处可以选择切或不切,但通过栈状态和数值比较进行剪枝,实际运行较快。
- 空间复杂度:,递归栈深度和栈存储。
思考
该解法通过回溯模拟在字符串中逐段切分,利用栈保存已确定的数字,并在切分时检查当前数字是否等于栈顶减 1。
优点:
- 直接模拟题意,逻辑清晰。
- 利用剪枝(只有满足等差条件才切分)大幅减少搜索空间。
- 能够正确处理最后一段数字的验证。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






