根据限制分割消息
难度:
标签:
题目描述
代码结果
运行时间: 71 ms, 内存: 18.3 MB
/*
* 思路:
* 使用Java Stream API,我们可以利用相同的逻辑来实现分割,但通过流处理来简化部分逻辑。
* 同样的,我们需要计算每个部分的有效信息长度,并判断其可行性。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class MessageSplitterStream {
public static List<String> splitMessage(String message, int limit) {
int n = message.length();
return IntStream.rangeClosed(1, n)
.mapToObj(b -> {
int suffixLength = ("<" + b + "/" + b + ">").length();
int maxPartLength = limit - suffixLength;
int totalValidLength = maxPartLength * b;
if (totalValidLength >= n) {
int[] currentIndex = {0};
return IntStream.rangeClosed(1, b)
.mapToObj(a -> {
int remainingParts = b - a + 1;
int remainingChars = n - currentIndex[0];
int partLength = Math.min(maxPartLength, remainingChars - remainingParts + 1);
String part = message.substring(currentIndex[0], currentIndex[0] + partLength) + "<" + a + "/" + b + ">";
currentIndex[0] += partLength;
return part;
}).collect(Collectors.toList());
}
return new ArrayList<String>();
}).filter(list -> !list.isEmpty()).findFirst().orElse(new ArrayList<>());
}
}
解释
方法:
此题解尝试通过一系列计算来确定如何有效分割字符串,以使每段的长度等于或小于给定的limit。解法考虑了每个部分结尾处的索引标记所需的额外字符数。不同的索引长度(1位、2位、3位或4位数字)会导致每部分可用于实际消息的字符数不同。题解先通过循环遍历四种情况来确定最少需要的部分数n。然后基于所需部分数n和每个部分的结尾长度,对消息进行分割。根据分割的部分数和每部分结尾所需的字符数,调整每次截取的字符串长度,确保每个部分满足长度要求。如果长度不够分配到每一部分,将返回空数组。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在计算每段可以分割的长度时,需要根据分段结束的数字的位数来减去不同的值?
▷🦆
在解决方案中,如何确保每次分割后部分的长度加上编号后的标记确实不会超过限制长度?
▷🦆
解决方案中提到如果`limit`小于一定值就直接返回空数组,这些特定的`limit`值是如何确定的?
▷🦆
在代码中,为什么要使用不同的循环来处理不同位数的数字编号?这样做的效率如何?
▷