题目解析
这道题目描述了一个规则化整理数组的过程,要求将输入的整数数组分组,按照一定规则输出。具体来说,每一组数字满足以下条件:
-
连续性:
- 每组中的数字是连续递增的,即每两个相邻数字的差值为1。
-
长度限制:
- 如果连续递增的数字序列长度 ≥3≥3,需要用范围表示,例如:
-3--1。 - 如果序列长度 <3<3,则每个数字都单独输出,例如:
2或10。
- 如果连续递增的数字序列长度 ≥3≥3,需要用范围表示,例如:
目标是将输入的整数数组按照上述规则分组,并以规定的字符串格式输出。
问题分解
输入与输出
-
输入
- 一个整数数组
plates,表示盘子的编号,长度为n。 - 数组已经按递增顺序排列。
- 一个整数数组
-
输出
- 一个字符串,表示盘子分组后的结果。组之间用逗号分隔:
- 连续递增长度 ≥3≥3 的组用
start-end表示。 - 其他数字直接用其值表示。
- 连续递增长度 ≥3≥3 的组用
- 一个字符串,表示盘子分组后的结果。组之间用逗号分隔:
分析规则与逻辑
1. 连续递增序列的判断
- 数字序列的连续递增需要满足
plates[i+1] - plates[i] = 1。 - 遍历数组时可以通过一个指针记录当前的连续起点
start,另一个指针end指向当前连续段的终点。 - 每次比较
plates[end+1]和plates[end]的差值,如果为1,则继续扩展当前序列;否则,记录该序列并重新开始下一段。
2. 序列长度的判断
- 当序列长度 (end - start + 1)≥3(end - start + 1)≥3 时,用
start-end格式输出。 - 当序列长度 <3<3 时,序列中的数字逐个输出。
3. 字符串拼接
- 每处理完一个序列,需要将结果拼接到最终输出字符串中。
- 使用逗号
,分隔不同序列。 - 为避免多余的逗号,需特别处理最后一段。
解题步骤
-
初始化变量
- 定义一个字符串构造器
result来拼接最终结果。 - 定义指针
start用于标记当前连续序列的起点。
- 定义一个字符串构造器
-
遍历数组
- 从左到右扫描数组,判断每个数字是否与其后续数字连续。
- 如果连续,将指针
end向右移动。 - 如果不连续或到达数组末尾,则判断当前序列的长度并按照规则拼接到结果中。
-
处理单独数字与范围
- 如果序列长度 ≥3≥3,拼接
plates[start]-plates[end]。 - 如果序列长度 <3<3,逐个拼接
plates[start], plates[start+1], ...。
- 如果序列长度 ≥3≥3,拼接
-
处理最后一个序列
- 由于遍历结束时可能还有一个未处理的序列,需要在遍历结束后再将剩余的序列处理并拼接到结果中。
-
返回结果
- 将拼接好的字符串作为最终输出。
测试样例分析
样例 1
- 输入:
plates = [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20] - 分析:
- 数组中连续段为:
-3, -2, -1:长度为3,输出-3--1。2:单个数字,输出2。10:单个数字,输出10。15, 16:长度为2,输出15,16。18, 19, 20:长度为3,输出18-20。
- 最终输出为:
"-3--1,2,10,15,16,18-20"。
- 数组中连续段为:
- 输出:
"-3--1,2,10,15,16,18-20"
样例 2
- 输入:
plates = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20] - 分析:
- 数组中连续段为:
-6:单个数字,输出-6。-3, -2, -1, 0, 1:长度为5,输出-3-1。3, 4, 5:长度为3,输出3-5。7, 8, 9, 10, 11:长度为5,输出7-11。14:单个数字,输出14。15:单个数字,输出15。17, 18, 19, 20:长度为4,输出17-20。
- 最终输出为:
"-6,-3-1,3-5,7-11,14,15,17-20"。
- 数组中连续段为:
- 输出:
"-6,-3-1,3-5,7-11,14,15,17-20"
样例 3
- 输入:
plates = [1, 2, 7, 8, 9, 10, 11, 19] - 分析:
- 数组中连续段为:
1, 2:长度为2,输出1,2。7, 8, 9, 10, 11:长度为5,输出7-11。19:单个数字,输出19。
- 最终输出为:
"1,2,7-11,19"。
- 数组中连续段为:
- 输出:
"1,2,7-11,19"
`public class Main { public static String solution(int[] plates, int n) { StringBuilder result = new StringBuilder(); int start = 0;
while (start < n) {
int end = start;
// 找到一个连续递增的序列
while (end + 1 < n && plates[end + 1] == plates[end] + 1) {
end++;
}
// 检查序列的长度
if (end - start >= 2) {
// 序列长度大于等于3,格式化为范围表示
result.append(plates[start]).append("-").append(plates[end]);
} else {
// 否则单个输出
for (int i = start; i <= end; i++) {
result.append(plates[i]);
if (i != end) {
result.append(",");
}
}
}
// 如果不是最后一个序列,则加上逗号
if (end + 1 < n) {
result.append(",");
}
// 移动到下一个序列
start = end + 1;
}
return result.toString();
}
public static void main(String[] args) {
// You can add more test cases here
System.out.println(solution(new int[]{-3, -2, -1, 2, 10, 15, 16, 18, 19, 20}, 10).equals("-3--1,2,10,15,16,18-20"));
System.out.println(solution(new int[]{-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}, 20).equals("-6,-3-1,3-5,7-11,14,15,17-20"));
System.out.println(solution(new int[]{1, 2, 7, 8, 9, 10, 11, 19}, 8).equals("1,2,7-11,19"));
}
}`
时间复杂度分析
-
遍历数组
- 数组长度为 nn,每个元素只被访问一次,因此时间复杂度为 O(n)O(n)。
-
字符串拼接
- 字符串拼接操作与连续段数量相关,总复杂度为 O(n)O(n)。
-
总体复杂度
- 时间复杂度为 O(n)O(n),空间复杂度为 O(n)O(n)(用于存储结果字符串)。
总结
本题通过对数组的连续性和长度规则进行分段处理,实现了高效的字符串拼接。算法核心在于利用指针记录连续段的起点和终点,按规则判断是否需要合并成范围或逐一输出。最终解决方案兼顾了效率和易读性,适用于各种长度的输入数组。