You are given a string s
that consists of only digits.
Check if we can split s
into two or more non-empty substrings such that the numerical values of the substrings are in descending order and the difference between numerical values of every two adjacent substrings is equal to 1
.
s = "0090089"
can be split into ["0090", "089"]
with numerical values [90,89]
. The values are in descending order and adjacent values differ by 1
, so this way is valid.s = "001"
can be split into ["0", "01"]
, ["00", "1"]
, or ["0", "0", "1"]
. However all the ways are invalid because they have numerical values [0,1]
, [0,1]
, and [0,0,1]
respectively, all of which are not in descending order.Return true
if it is possible to split s
as described above, or false
otherwise.
A substring is a contiguous sequence of characters in a string.
Example 1:
Input: s = "1234" Output: false Explanation: There is no valid way to split s.
Example 2:
Input: s = "050043" Output: true Explanation: s can be split into ["05", "004", "3"] with numerical values [5,4,3]. The values are in descending order with adjacent values differing by 1.
Example 3:
Input: s = "9080701" Output: false Explanation: There is no valid way to split s.
Constraints:
1 <= s.length <= 20
s
only consists of digits.This problem asks whether a string s
consisting only of digits can be split into two or more non-empty substrings such that their numerical values are in descending order with a difference of 1 between consecutive values. A recursive Depth-First Search (DFS) approach effectively explores all possible splits.
Algorithm:
The core of the solution is a recursive function dfs(i, x)
.
i
: The index of the current character in the string s
. It indicates where the next substring starts.x
: The numerical value of the previously extracted substring. Initially, x
is -1 to signify no previous substring.The function operates as follows:
Base Case: If i
reaches the end of the string (i >= len(s)
), it means we've successfully split the entire string into substrings meeting the conditions. Return true
.
Iterate through possible substrings: The code iterates through all possible substrings starting from index i
. It constructs the numerical value (y
) of each potential substring.
Check conditions: Before recursively calling dfs
, it checks two crucial conditions:
x
negative (no previous substring) or is x - y == 1
(difference is 1)? This ensures the descending order and difference constraint.dfs(j + 1, y)
recursively explores the remaining part of the string, starting from the index j + 1
(after the current substring) with the current substring's value y
as the new x
.Return value: If the recursive call returns true
, it implies a valid split is found; otherwise, the function continues to explore other possible substrings. If no valid split is found after trying all substrings starting from index i
, the function returns false
.
Time Complexity: O(2n * n), where n is the length of the string. In the worst case, the algorithm explores all possible ways to split the string, and each split requires calculating the numerical value of a substring (O(n) in the worst case). The exponential component comes from the branching nature of the recursion. While the worst case is exponential, in practice, it often performs much better because many splits will fail early.
Space Complexity: O(n) due to the recursive call stack. The depth of the recursion can be at most n.
Code Examples (Python3):
class Solution:
def splitString(self, s: str) -> bool:
def dfs(i: int, x: int) -> bool:
if i >= len(s):
return True # Successfully split the entire string
y = 0
r = len(s) - 1 if x < 0 else len(s) # optimization to avoid out-of-bounds in the loop
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)
The other language examples follow a similar structure, differing only in syntax and data type handling. The core recursive logic remains consistent across all implementations. Note that large numbers could lead to integer overflow issues if not handled properly (as in the C++ example).