将字符串分割成值不超过 K 的子字符串
难度:
标签:
题目描述
代码结果
运行时间: 44 ms, 内存: 16.5 MB
/*
* 思路:
* 使用Java Stream的方式来实现同样的逻辑,避免使用嵌套循环。
* 我们仍然需要动态规划数组dp来存储最小分割数。
*/
import java.util.stream.IntStream;
public class GoodSplitStream {
public int minimumGoodSplit(String s, int k) {
int n = s.length();
int[] dp = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
IntStream.rangeClosed(1, n).forEach(j -> {
IntStream.rangeClosed(1, j).map(i -> j - i + 1).forEach(i -> {
String sub = s.substring(i - 1, j);
if (Long.parseLong(sub) <= k) {
dp[j] = Math.min(dp[j], dp[i - 1] + 1);
}
});
});
return dp[n] == Integer.MAX_VALUE ? -1 : dp[n];
}
}
解释
方法:
此题解采用了贪心算法,目标是最小化分割子字符串的数量,同时每个子字符串的整数值不超过给定的k。首先,根据k的大小决定最大可能的子字符串长度(siz),这是通过计算k可以有多少位数来确定的。例如,如果k是60,则最大可能的子字符串长度是2,因为60是两位数。接着,根据siz尝试从字符串s的左侧开始尽可能地切分长度为siz的子字符串,同时确保每个子字符串的数值不超过k。如果在某个位置上无法进行这样的切分,尝试减少一个字符,使长度变为siz-1,再次检查是否满足条件。如果仍不满足条件,则返回-1,表示无法进行好分割。这个过程重复直到字符串的末尾。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在计算最大可能的子字符串长度时,仅考虑了k可以有多少位数,而没有考虑数字序列的具体组合?
▷🦆
当k的位数为1时,解法中直接对字符串s中的每个数字进行比较,这种方法是否在所有情况下都有效?
▷🦆
在尝试切分长度为siz的子字符串时,如果子字符串的起始位置加上siz超过了字符串s的长度,该如何处理?
▷🦆
解法提到如果无法进行切分,则尝试减少一个字符,这种策略是否可能导致漏掉某些有效的分割方式?
▷