问题背景
小M喜欢用一种特别的方式整理他家里的盘子。每当用餐完毕后,他会将盘子按照它们的序号顺序叠放起来。这些盘子的序号都是独一无二的整数,并且在开始整理之前已经是递增排列的了。小M叠放盘子的规则是:每一堆盘子的序号必须是连续递增的,并且每堆至少要有三个盘子。如果不能满足这个条件,那么这些盘子就需要单独列出。
输入输出示例
-
样例1:
- 输入:
plates = [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20],n = 10 - 输出:
"-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],n = 20 - 输出:
"-6,-3-1,3-5,7-11,14,15,17-20"
- 输入:
-
样例3:
- 输入:
plates = [1, 2, 7, 8, 9, 10, 11, 19],n = 8 - 输出:
"1,2,7-11,19"
- 输入:
解题思路
这个问题的核心在于识别出哪些盘子可以组成一组(即连续递增且至少有三个盘子),以及如何处理那些不能形成组的单个盘子或盘子对。我们可以通过遍历给定的盘子列表来实现这一目标,同时记录当前连续序列的起始位置和结束位置。当遇到不连续的情况时,检查已记录的序列是否符合组的要求,然后重置起始和结束位置以开始新的序列。
代码解析
#include <iostream>
#include <string>
#include <vector>
// 主要的解决方案函数
std::string solution(std::vector<int> &plates, int n) {
std::string result = ""; // 初始化结果字符串
int start = 0; // 当前连续序列的起始索引
int end = 0; // 当前连续序列的结束索引
// 遍历盘子列表
for (int i = 1; i < n; ++i) {
if (plates[i] == plates[i - 1] + 1) { // 检查当前盘子是否与前一个盘子连续
end = i; // 更新结束索引
} else { // 如果不连续
if (end - start >= 2) { // 检查连续序列是否至少有3个盘子
result += std::to_string(plates[start]) + "-" + std::to_string(plates[end]) + ","; // 添加到结果中
} else { // 如果序列小于3个盘子
for (int j = start; j <= end; ++j) { // 将每个盘子单独添加到结果中
result += std::to_string(plates[j]) + ",";
}
}
// 重新设置起始和结束索引
start = i;
end = i;
}
}
// 处理最后一个序列
if (end - start >= 2) {
result += std::to_string(plates[start]) + "-" + std::to_string(plates[end]);
} else {
for (int j = start; j <= end; ++j) {
result += std::to_string(plates[j]) + ",";
}
}
// 删除结果字符串末尾多余的逗号
if (!result.empty() && result.back() == ',') {
result.pop_back();
}
return result; // 返回最终的结果
}
定义解决方案函数
cpp
std::string solution(std::vector<int> &plates, int n) {
std::string result = ""; // 初始化结果字符串
int start = 0; // 当前连续序列的起始索引
int end = 0; // 当前连续序列的结束索引
std::string result = "":初始化一个空字符串,用于存储最终的结果。int start = 0:初始化当前连续序列的起始索引。int end = 0:初始化当前连续序列的结束索引。
遍历盘子列表
cpp
for (int i = 1; i < n; ++i) {
if (plates[i] == plates[i - 1] + 1) { // 检查当前盘子是否与前一个盘子连续
end = i; // 更新结束索引
} else { // 如果不连续
if (end - start >= 2) { // 检查连续序列是否至少有3个盘子
result += std::to_string(plates[start]) + "-" + std::to_string(plates[end]) + ","; // 添加到结果中
} else { // 如果序列小于3个盘子
for (int j = start; j <= end; ++j) { // 将每个盘子单独添加到结果中
result += std::to_string(plates[j]) + ",";
}
}
// 重新设置起始和结束索引
start = i;
end = i;
}
}
-
for (int i = 1; i < n; ++i):从第二个盘子开始遍历整个列表。 -
if (plates[i] == plates[i - 1] + 1):检查当前盘子是否与前一个盘子连续。- 如果连续,更新
end为当前索引i。
- 如果连续,更新
-
else:如果不连续,处理当前连续序列。-
if (end - start >= 2):检查当前连续序列是否至少有3个盘子。- 如果是,将该序列格式化为
start-end并添加到结果字符串中。
- 如果是,将该序列格式化为
-
else:如果序列小于3个盘子。- 使用一个内循环将每个盘子单独添加到结果字符串中。
-
-
start = i; end = i;:更新start和end为当前索引i,开始新的序列。
处理最后一个序列
cpp
if (end - start >= 2) {
result += std::to_string(plates[start]) + "-" + std::to_string(plates[end]);
} else {
for (int j = start; j <= end; ++j) {
result += std::to_string(plates[j]) + ",";
}
}
-
if (end - start >= 2):检查最后一个序列是否至少有3个盘子。- 如果是,将该序列格式化为
start-end并添加到结果字符串中。
- 如果是,将该序列格式化为
-
else:如果序列小于3个盘子。- 使用一个内循环将每个盘子单独添加到结果字符串中。
删除结果字符串末尾多余的逗号
cpp
深色版本
if (!result.empty() && result.back() == ',') {
result.pop_back();
}
-
if (!result.empty() && result.back() == ','):检查结果字符串是否非空且最后一个字符是逗号。- 如果是,删除最后一个字符(逗号)。