盘子叠放问题解析
问题描述
小M有一个独特的方式来收拾家中的盘子。每次用餐后,他会将盘子按照它们的序号顺序叠放。盘子的序号都是唯一的整数,并且在收拾前就是递增的。小M的叠放规则是,每一堆盘子的序号都是连续递增的,并且至少包含3个盘子。
需要编写程序帮助小M确定盘子的叠放方式。
示例:
- 输入:
plates = [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20],n = 10 - 输出:
"-3--1,2,10,15,16,18-20"
连续递增序列 -3, -2, -1 可以叠在一起表示为 -3--1,而 18, 19, 20 可以叠在一起表示为 18-20。不满足连续递增至少3个的,如 2, 10, 15, 16,都应单独列出。
解题思路
为了满足小M的叠放规则,需要遍历盘子的序号数组,识别连续递增的序列,并根据序列长度决定如何表示:
-
初始化变量:
- 使用一个变量
start标记当前连续序列的起始位置。 - 使用
StringBuilder来构建最终的输出字符串。
- 使用一个变量
-
遍历数组:
- 从第二个元素开始遍历数组,比较当前元素和前一个元素的差值。
- 如果差值为1,表示序号是连续的,继续遍历。
-
确定序列的结束:
-
当发现当前元素和前一个元素不连续,或者已经遍历到数组末尾时,需要处理当前的连续序列。
-
根据序列长度进行不同的处理:
- 长度大于等于3:表示为
start-end,例如-3--1。 - 长度为2:单独列出每个盘子的序号,使用逗号分隔,例如
15,16。 - 长度为1:直接输出该盘子的序号。
- 长度大于等于3:表示为
-
-
更新起始位置:
- 在处理完当前序列后,更新
start为当前元素的位置,继续检查后续的盘子。
- 在处理完当前序列后,更新
-
构建结果字符串:
- 在每次处理序列时,将结果添加到
StringBuilder中,并在末尾添加逗号。 - 遍历结束后,删除最后一个多余的逗号。
- 在每次处理序列时,将结果添加到
代码详解
下面是实现上述思路的 Java 代码:
public static String solution(int[] plates, int n) {
// 如果输入为空或长度为 0,直接返回空字符串
if (plates == null || n == 0) {
return "";
}
StringBuilder result = new StringBuilder();
int start = 0; // 当前连续序列的起始位置
// 遍历 plates 数组
for (int i = 1; i <= n; i++) {
// 如果到达数组末尾,或者当前元素和前一个元素不连续
if (i == n || plates[i] - plates[i - 1] != 1) {
if (i - start >= 3) {
// 序列长度大于等于 3,使用 "start-end" 表示
result.append(plates[start]).append("-").append(plates[i - 1]).append(",");
} else {
// 序列长度小于 3,单独输出每个元素
for (int j = start; j < i; j++) {
result.append(plates[j]).append(",");
}
}
start = i; // 更新起始位置
}
}
// 删除最后一个多余的逗号
if (result.length() > 0) {
result.deleteCharAt(result.length() - 1);
}
return result.toString();
}
代码解释
-
主要步骤:
-
输入检查:
if (plates == null || n == 0) { return ""; }- 如果输入为空或盘子数量为 0,返回空字符串。
-
初始化变量:
StringBuilder result = new StringBuilder(); int start = 0;result用于构建最终的输出字符串。start标记当前连续序列的起始位置。
-
遍历数组:
for (int i = 1; i <= n; i++) {- 从索引
1开始遍历到n,注意这里使用<= n,以便在数组末尾处理最后的序列。
- 从索引
-
检测序列结束条件:
if (i == n || plates[i] - plates[i - 1] != 1) {- 当到达数组末尾,或者当前元素和前一个元素不连续时,处理当前序列。
-
根据序列长度处理:
-
序列长度大于等于 3:
if (i - start >= 3) { result.append(plates[start]).append("-").append(plates[i - 1]).append(","); }- 使用 "start-end" 的格式添加到结果中。
-
序列长度小于 3:
else { for (int j = start; j < i; j++) { result.append(plates[j]).append(","); } }- 逐个添加序列中的盘子序号。
-
-
更新起始位置:
start = i;- 准备处理下一个序列。
-
删除最后一个逗号:
if (result.length() > 0) { result.deleteCharAt(result.length() - 1); }- 确保输出格式正确,没有多余的逗号。
-
结论
该算法的时间复杂度为 O(n),因为只需要一次遍历即可完成所有操作。
作者:AWM