腾讯0708面试手撕题:严格递增数字分割
题目
给定一个数字字符串 s,请你将其分割成至少两个非空子串,使得每个子串满足以下条件:
无前导零:如果子串长度大于1,则不能以 '0' 开头。
严格递增:每个子串表示的数值必须严格大于前一个子串的数值。
返回所有可能的分割方案,方案中的子串按顺序排列。你可以以任意顺序返回答案。
示例 1:
输入:s = "1234"
输出: [ ["1","2","3","4"], ["1","2","34"], ["12","34"], ["1","234"] ]
解释:所有分割方案均满足条件。例如,分割 ["1","23","4"] 无效,因为 23 > 4 不满足严格递增。
示例 2:
输入:s = "1023"
输出: [ ["10","23"] ]
解释:唯一有效的分割是 ["10","23"],其中 10 < 23 且无前导零。
示例 3:
输入:s = "10"
输出: []
解释:唯一可能的分割是 ["1","0"],但 1 > 0,不满足条件。
解答
使用深度优先搜索(DFS)回溯算法解决严格递增数字分割问题,核心思路是递归尝试所有可能的分割点,并在过程中验证子串的合法性。
代码如下:
def splitIntoIncreasing(s):results = []n = len(s)def dfs(start, path, last):if start == n:if len(path) >= 2:results.append(path)returnfor end in range(start + 1, n + 1):curr_str = s[start:end]if len(curr_str) > 1 and curr_str[0] == '0':continueif path:last_str = lastlen_last = len(last_str)len_curr = len(curr_str)if len_last < len_curr or (len_last == len_curr and last_str < curr_str):dfs(end, path + [curr_str], curr_str)else:dfs(end, [curr_str], curr_str)dfs(0, [], "")return resultss = "10235432243"
print(splitIntoIncreasing(s))
'''
[['10', '23', '54', '32243'], ['10', '23', '543', '2243'], ['10', '23', '5432243'], ['10', '235', '432243'], ['10', '2354', '32243'], ['10', '235432243'], ['102', '354', '32243'], ['102', '35432243'], ['1023', '5432243'], ['10235', '432243']]
'''