diff --git a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README.md b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README.md index 70c1ac5651f29..bfb0df5c6933b 100644 --- a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README.md +++ b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README.md @@ -84,9 +84,15 @@ tags: ### 方法一:DFS -从字符串的第一个字符开始,枚举所有可能的拆分位置,判断拆分出来的子串是否满足题目要求,如果满足则继续递归判断剩余的子串是否满足题目要求,直到遍历完整个字符串。 +我们可以从字符串的第一个字符开始,尝试将其拆分成一个或多个子字符串,然后递归处理剩余的部分。 -时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为字符串的长度。 +具体地,我们设计一个函数 $\textit{dfs}(i, x)$,其中 $i$ 表示当前处理到的位置,而 $x$ 表示上一个拆分出的数值。初始时 $x = -1$,表示我们还没有拆分出任何数值。 + +在 $\textit{dfs}(i, x)$ 中,我们首先计算当前拆分出的数值 $y$,如果 $x = -1$,或者 $x - y = 1$,那么我们可以尝试将 $y$ 作为下一个数值,继续递归处理剩余的部分。如果递归的结果为 $\textit{true}$,我们就找到了一种拆分方法,返回 $\textit{true}$。 + +遍历完所有的拆分方法后,如果没有找到合适的拆分方法,我们返回 $\textit{false}$。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$,其中 $n$ 是字符串的长度。 @@ -95,38 +101,40 @@ tags: ```python class Solution: def splitString(self, s: str) -> bool: - def dfs(i, x, k): - if i == len(s): - return k > 1 + def dfs(i: int, x: int) -> bool: + if i >= len(s): + return True y = 0 - for j in range(i, len(s)): + r = len(s) - 1 if x < 0 else len(s) + for j in range(i, r): y = y * 10 + int(s[j]) - if (x == -1 or x - y == 1) and dfs(j + 1, y, k + 1): + if (x < 0 or x - y == 1) and dfs(j + 1, y): return True return False - return dfs(0, -1, 0) + return dfs(0, -1) ``` #### Java ```java class Solution { - private String s; + private char[] s; public boolean splitString(String s) { - this.s = s; - return dfs(0, -1, 0); + this.s = s.toCharArray(); + return dfs(0, -1); } - private boolean dfs(int i, long x, int k) { - if (i == s.length()) { - return k > 1; + private boolean dfs(int i, long x) { + if (i >= s.length) { + return true; } long y = 0; - for (int j = i; j < s.length(); ++j) { - y = y * 10 + (s.charAt(j) - '0'); - if ((x == -1 || x - y == 1) && dfs(j + 1, y, k + 1)) { + int r = x < 0 ? s.length - 1 : s.length; + for (int j = i; j < r; ++j) { + y = y * 10 + s[j] - '0'; + if ((x < 0 || x - y == 1) && dfs(j + 1, y)) { return true; } } @@ -141,23 +149,24 @@ class Solution { class Solution { public: bool splitString(string s) { - function dfs = [&](int i, long long x, int k) -> bool { - if (i == s.size()) { - return k > 1; + auto dfs = [&](auto&& dfs, int i, long long x) -> bool { + if (i >= s.size()) { + return true; } long long y = 0; - for (int j = i; j < s.size(); ++j) { - y = y * 10 + (s[j] - '0'); + int r = x < 0 ? s.size() - 1 : s.size(); + for (int j = i; j < r; ++j) { + y = y * 10 + s[j] - '0'; if (y > 1e10) { break; } - if ((x == -1 || x - y == 1) && dfs(j + 1, y, k + 1)) { + if ((x < 0 || x - y == 1) && dfs(dfs, j + 1, y)) { return true; } } return false; }; - return dfs(0, -1, 0); + return dfs(dfs, 0, -1); } }; ``` @@ -166,24 +175,47 @@ public: ```go func splitString(s string) bool { - var dfs func(i, x, k int) bool - dfs = func(i, x, k int) bool { - if i == len(s) { - return k > 1 + var dfs func(i, x int) bool + dfs = func(i, x int) bool { + if i >= len(s) { + return true } y := 0 - for j := i; j < len(s); j++ { + r := len(s) + if x < 0 { + r-- + } + for j := i; j < r; j++ { y = y*10 + int(s[j]-'0') - if y > int(1e10) { - break - } - if (x == -1 || x-y == 1) && dfs(j+1, y, k+1) { + if (x < 0 || x-y == 1) && dfs(j+1, y) { return true } } return false } - return dfs(0, -1, 0) + return dfs(0, -1) +} +``` + +#### TypeScript + +```ts +function splitString(s: string): boolean { + const dfs = (i: number, x: number): boolean => { + if (i >= s.length) { + return true; + } + let y = 0; + const r = x < 0 ? s.length - 1 : s.length; + for (let j = i; j < r; ++j) { + y = y * 10 + +s[j]; + if ((x < 0 || x - y === 1) && dfs(j + 1, y)) { + return true; + } + } + return false; + }; + return dfs(0, -1); } ``` diff --git a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README_EN.md b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README_EN.md index 86bb4bdd1a081..f50ef0539ec34 100644 --- a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README_EN.md +++ b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/README_EN.md @@ -72,11 +72,17 @@ The values are in descending order with adjacent values differing by 1. -### Solution 1: DFS (Depth-First Search) +### Solution 1: DFS -Starting from the first character of the string, enumerate all possible split positions. Check if the split substring meets the requirements of the problem. If it does, continue to recursively check whether the remaining substring meets the requirements, until the entire string is traversed. +We can start from the first character of the string and try to split it into one or more substrings, then recursively process the remaining part. -The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Where $n$ is the length of the string. +Specifically, we design a function $\textit{dfs}(i, x)$, where $i$ represents the current position being processed, and $x$ represents the last split value. Initially, $x = -1$, indicating that we have not split out any value yet. + +In $\textit{dfs}(i, x)$, we first calculate the current split value $y$. If $x = -1$, or $x - y = 1$, then we can try to use $y$ as the next value and continue to recursively process the remaining part. If the result of the recursion is $\textit{true}$, we have found a valid split method and return $\textit{true}$. + +After traversing all possible split methods, if no valid split method is found, we return $\textit{false}$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$, where $n$ is the length of the string. @@ -85,38 +91,40 @@ The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Where $n$ i ```python class Solution: def splitString(self, s: str) -> bool: - def dfs(i, x, k): - if i == len(s): - return k > 1 + def dfs(i: int, x: int) -> bool: + if i >= len(s): + return True y = 0 - for j in range(i, len(s)): + r = len(s) - 1 if x < 0 else len(s) + for j in range(i, r): y = y * 10 + int(s[j]) - if (x == -1 or x - y == 1) and dfs(j + 1, y, k + 1): + if (x < 0 or x - y == 1) and dfs(j + 1, y): return True return False - return dfs(0, -1, 0) + return dfs(0, -1) ``` #### Java ```java class Solution { - private String s; + private char[] s; public boolean splitString(String s) { - this.s = s; - return dfs(0, -1, 0); + this.s = s.toCharArray(); + return dfs(0, -1); } - private boolean dfs(int i, long x, int k) { - if (i == s.length()) { - return k > 1; + private boolean dfs(int i, long x) { + if (i >= s.length) { + return true; } long y = 0; - for (int j = i; j < s.length(); ++j) { - y = y * 10 + (s.charAt(j) - '0'); - if ((x == -1 || x - y == 1) && dfs(j + 1, y, k + 1)) { + int r = x < 0 ? s.length - 1 : s.length; + for (int j = i; j < r; ++j) { + y = y * 10 + s[j] - '0'; + if ((x < 0 || x - y == 1) && dfs(j + 1, y)) { return true; } } @@ -131,23 +139,24 @@ class Solution { class Solution { public: bool splitString(string s) { - function dfs = [&](int i, long long x, int k) -> bool { - if (i == s.size()) { - return k > 1; + auto dfs = [&](auto&& dfs, int i, long long x) -> bool { + if (i >= s.size()) { + return true; } long long y = 0; - for (int j = i; j < s.size(); ++j) { - y = y * 10 + (s[j] - '0'); + int r = x < 0 ? s.size() - 1 : s.size(); + for (int j = i; j < r; ++j) { + y = y * 10 + s[j] - '0'; if (y > 1e10) { break; } - if ((x == -1 || x - y == 1) && dfs(j + 1, y, k + 1)) { + if ((x < 0 || x - y == 1) && dfs(dfs, j + 1, y)) { return true; } } return false; }; - return dfs(0, -1, 0); + return dfs(dfs, 0, -1); } }; ``` @@ -156,24 +165,47 @@ public: ```go func splitString(s string) bool { - var dfs func(i, x, k int) bool - dfs = func(i, x, k int) bool { - if i == len(s) { - return k > 1 + var dfs func(i, x int) bool + dfs = func(i, x int) bool { + if i >= len(s) { + return true } y := 0 - for j := i; j < len(s); j++ { + r := len(s) + if x < 0 { + r-- + } + for j := i; j < r; j++ { y = y*10 + int(s[j]-'0') - if y > int(1e10) { - break - } - if (x == -1 || x-y == 1) && dfs(j+1, y, k+1) { + if (x < 0 || x-y == 1) && dfs(j+1, y) { return true } } return false } - return dfs(0, -1, 0) + return dfs(0, -1) +} +``` + +#### TypeScript + +```ts +function splitString(s: string): boolean { + const dfs = (i: number, x: number): boolean => { + if (i >= s.length) { + return true; + } + let y = 0; + const r = x < 0 ? s.length - 1 : s.length; + for (let j = i; j < r; ++j) { + y = y * 10 + +s[j]; + if ((x < 0 || x - y === 1) && dfs(j + 1, y)) { + return true; + } + } + return false; + }; + return dfs(0, -1); } ``` diff --git a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.cpp b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.cpp index 5e1c28e619df3..45173c4a7cdd5 100644 --- a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.cpp +++ b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.cpp @@ -1,22 +1,23 @@ class Solution { public: bool splitString(string s) { - function dfs = [&](int i, long long x, int k) -> bool { - if (i == s.size()) { - return k > 1; + auto dfs = [&](auto&& dfs, int i, long long x) -> bool { + if (i >= s.size()) { + return true; } long long y = 0; - for (int j = i; j < s.size(); ++j) { - y = y * 10 + (s[j] - '0'); + int r = x < 0 ? s.size() - 1 : s.size(); + for (int j = i; j < r; ++j) { + y = y * 10 + s[j] - '0'; if (y > 1e10) { break; } - if ((x == -1 || x - y == 1) && dfs(j + 1, y, k + 1)) { + if ((x < 0 || x - y == 1) && dfs(dfs, j + 1, y)) { return true; } } return false; }; - return dfs(0, -1, 0); + return dfs(dfs, 0, -1); } -}; \ No newline at end of file +}; diff --git a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.go b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.go index 32c8b798cd992..2f8ee676c55e6 100644 --- a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.go +++ b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.go @@ -1,20 +1,21 @@ func splitString(s string) bool { - var dfs func(i, x, k int) bool - dfs = func(i, x, k int) bool { - if i == len(s) { - return k > 1 + var dfs func(i, x int) bool + dfs = func(i, x int) bool { + if i >= len(s) { + return true } y := 0 - for j := i; j < len(s); j++ { + r := len(s) + if x < 0 { + r-- + } + for j := i; j < r; j++ { y = y*10 + int(s[j]-'0') - if y > int(1e10) { - break - } - if (x == -1 || x-y == 1) && dfs(j+1, y, k+1) { + if (x < 0 || x-y == 1) && dfs(j+1, y) { return true } } return false } - return dfs(0, -1, 0) -} \ No newline at end of file + return dfs(0, -1) +} diff --git a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.java b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.java index 584b3fafa2b49..8bb1a58e6a668 100644 --- a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.java +++ b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.java @@ -1,22 +1,23 @@ class Solution { - private String s; + private char[] s; public boolean splitString(String s) { - this.s = s; - return dfs(0, -1, 0); + this.s = s.toCharArray(); + return dfs(0, -1); } - private boolean dfs(int i, long x, int k) { - if (i == s.length()) { - return k > 1; + private boolean dfs(int i, long x) { + if (i >= s.length) { + return true; } long y = 0; - for (int j = i; j < s.length(); ++j) { - y = y * 10 + (s.charAt(j) - '0'); - if ((x == -1 || x - y == 1) && dfs(j + 1, y, k + 1)) { + int r = x < 0 ? s.length - 1 : s.length; + for (int j = i; j < r; ++j) { + y = y * 10 + s[j] - '0'; + if ((x < 0 || x - y == 1) && dfs(j + 1, y)) { return true; } } return false; } -} \ No newline at end of file +} diff --git a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.py b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.py index 6e4bb0f29830b..9d7e0f4f25fe9 100644 --- a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.py +++ b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.py @@ -1,13 +1,14 @@ class Solution: def splitString(self, s: str) -> bool: - def dfs(i, x, k): - if i == len(s): - return k > 1 + def dfs(i: int, x: int) -> bool: + if i >= len(s): + return True y = 0 - for j in range(i, len(s)): + r = len(s) - 1 if x < 0 else len(s) + for j in range(i, r): y = y * 10 + int(s[j]) - if (x == -1 or x - y == 1) and dfs(j + 1, y, k + 1): + if (x < 0 or x - y == 1) and dfs(j + 1, y): return True return False - return dfs(0, -1, 0) + return dfs(0, -1) diff --git a/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.ts b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.ts new file mode 100644 index 0000000000000..dd3acc0cf3fae --- /dev/null +++ b/solution/1800-1899/1849.Splitting a String Into Descending Consecutive Values/Solution.ts @@ -0,0 +1,17 @@ +function splitString(s: string): boolean { + const dfs = (i: number, x: number): boolean => { + if (i >= s.length) { + return true; + } + let y = 0; + const r = x < 0 ? s.length - 1 : s.length; + for (let j = i; j < r; ++j) { + y = y * 10 + +s[j]; + if ((x < 0 || x - y === 1) && dfs(j + 1, y)) { + return true; + } + } + return false; + }; + return dfs(0, -1); +}