LeetCode 题解工作台

将字符串拆分为递减的连续值

给你一个仅由数字组成的字符串 s 。 请你判断能否将 s 拆分成两个或者多个 非空子字符串 ,使子字符串的 数值 按 降序 排列,且每两个 相邻子字符串 的数值之 差 等于 1 。 例如,字符串 s = "0090089" 可以拆分成 ["0090", "089"] ,数值为 [90,89] 。这些…

category

3

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

中等 · 回溯·pruning

bolt

答案摘要

我们可以从字符串的第一个字符开始,尝试将其拆分成一个或多个子字符串,然后递归处理剩余的部分。 具体地,我们设计一个函数 $\textit{dfs}(i, x)$,其中 表示当前处理到的位置,而 表示上一个拆分出的数值。初始时 $x = -1$,表示我们还没有拆分出任何数值。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 回溯·pruning 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个仅由数字组成的字符串 s

请你判断能否将 s 拆分成两个或者多个 非空子字符串 ,使子字符串的 数值降序 排列,且每两个 相邻子字符串 的数值之 等于 1

  • 例如,字符串 s = "0090089" 可以拆分成 ["0090", "089"] ,数值为 [90,89] 。这些数值满足按降序排列,且相邻值相差 1 ,这种拆分方法可行。
  • 另一个例子中,字符串 s = "001" 可以拆分成 ["0", "01"]["00", "1"]["0", "0", "1"] 。然而,所有这些拆分方法都不可行,因为对应数值分别是 [0,1][0,1][0,0,1] ,都不满足按降序排列的要求。

如果可以按要求拆分 s ,返回 true ;否则,返回 false

子字符串 是字符串中的一个连续字符序列。

 

示例 1:

输入:s = "1234"
输出:false
解释:不存在拆分 s 的可行方法。

示例 2:

输入:s = "050043"
输出:true
解释:s 可以拆分为 ["05", "004", "3"] ,对应数值为 [5,4,3] 。
满足按降序排列,且相邻值相差 1

示例 3:

输入:s = "9080701"
输出:false
解释:不存在拆分 s 的可行方法。

示例 4:

输入:s = "10009998"
输出:true
解释:s 可以拆分为 ["100", "099", "98"] ,对应数值为 [100,99,98] 。
满足按降序排列,且相邻值相差 1

 

提示:

  • 1 <= s.length <= 20
  • s 仅由数字组成
lightbulb

解题思路

方法一:DFS

我们可以从字符串的第一个字符开始,尝试将其拆分成一个或多个子字符串,然后递归处理剩余的部分。

具体地,我们设计一个函数 dfs(i,x)\textit{dfs}(i, x),其中 ii 表示当前处理到的位置,而 xx 表示上一个拆分出的数值。初始时 x=1x = -1,表示我们还没有拆分出任何数值。

dfs(i,x)\textit{dfs}(i, x) 中,我们首先计算当前拆分出的数值 yy,如果 x=1x = -1,或者 xy=1x - y = 1,那么我们可以尝试将 yy 作为下一个数值,继续递归处理剩余的部分。如果递归的结果为 true\textit{true},我们就找到了一种拆分方法,返回 true\textit{true}

遍历完所有的拆分方法后,如果没有找到合适的拆分方法,我们返回 false\textit{false}

时间复杂度 O(n2)O(n^2),空间复杂度 O(n)O(n),其中 nn 是字符串的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution:
    def splitString(self, s: str) -> bool:
        def dfs(i: int, x: int) -> bool:
            if i >= len(s):
                return True
            y = 0
            r = len(s) - 1 if x < 0 else len(s)
            for j in range(i, r):
                y = y * 10 + int(s[j])
                if (x < 0 or x - y == 1) and dfs(j + 1, y):
                    return True
            return False

        return dfs(0, -1)
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    The candidate demonstrates a strong understanding of backtracking and can apply pruning techniques to avoid unnecessary computations.

  • question_mark

    The candidate is careful with string parsing, ensuring that leading zeros are handled appropriately.

  • question_mark

    The candidate is able to explain the trade-offs between exhaustive search and efficient pruning in solving the problem.

warning

常见陷阱

外企场景
  • error

    Failing to handle leading zeros correctly, which can lead to incorrect number comparisons.

  • error

    Not pruning the search space effectively, leading to excessive computation time.

  • error

    Overlooking edge cases, such as very short strings or strings where no valid split is possible.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Allowing strings to have leading zeros in some cases.

  • arrow_right_alt

    Trying a more optimized approach that uses dynamic programming instead of backtracking.

  • arrow_right_alt

    Increasing the string length limit to test the scalability of the solution.

help

常见问题

外企场景

将字符串拆分为递减的连续值题解:回溯·pruning | LeetCode #1849 中等