叠盘子排序 | 豆包MarsCode AI刷题

2 阅读4分钟

问题描述

小M有一个独特的方式来收拾家中的盘子。每次用餐后,他会将盘子按照他们的序号顺序叠放。盘子的序号都是唯一的整数,并且在收拾前就是递增的。小M的叠放规则是,每一堆盘子的序号都是连续递增的,并且至少包含3个盘子。需要编写程序帮助小M确定盘子的叠放方式。

例如,输入的盘子序号是 [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20],按照小M的规则,连续递增序列 -3, -2, -1 可以叠在一起表示为 -3--1,而 18, 19, 20 可以叠在一起表示为 18-20。不满足连续递增至少3个的,如 2, 10, 15, 16 都应单独列出。


输入参数

  • plates: 一个整数数组,表示盘子的序号
  • n: 盘子总数

测试样例

样例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"

解题思路

  1. 遍历数组:从第一个盘子开始,遍历整个数组。
  2. 寻找连续序列:检查当前盘子是否与前一个盘子连续。如果是,继续检查下一个盘子,直到不再连续。
  3. 判断序列长度:如果连续序列的长度大于等于3,将其格式化为 start-end 的形式;否则,单独列出每个盘子。
  4. 拼接结果:将所有处理后的序列拼接成一个字符串。

代码详解

#include <string>
#include <vector>

std::string solution(std::vector<int> &plates, int n) {
  std::string result;
  int i = 0;

  while (i < n) {
    int start = i;

    // 找到连续序列的结束位置
    while (i + 1 < n && plates[i + 1] == plates[i] + 1) {
      i++;
    }

    int end = i;

    // 判断序列长度是否大于等于3
    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 (j < end) result += ",";
      }
    }

    // 如果不是最后一个元素,添加逗号分隔符
    if (i < n - 1) result += ",";

    i++;
  }

  return result;
}

int main() {
  // 你可以添加更多测试用例
  std::vector<int> plates1 = {-3, -2, -1, 2, 10, 15, 16, 18, 19, 20};
  std::cout << (solution(plates1, 10) == "-3--1,2,10,15,16,18-20") << std::endl;

  std::vector<int> plates2 = {-6, -3, -2, -1, 0,  1,  3,  4,  5,  7,
                              8,  9,  10, 11, 14, 15, 17, 18, 19, 20};
  std::cout << (solution(plates2, 20) == "-6,-3-1,3-5,7-11,14,15,17-20")
            << std::endl;

  std::vector<int> plates3 = {1, 2, 7, 8, 9, 10, 11, 19};
  std::cout << (solution(plates3, 8) == "1,2,7-11,19") << std::endl;

  return 0;
}
  1. 遍历数组

    从第一个盘子开始遍历数组,start 记录当前连续序列的起始位置。

  2. 寻找连续序列的结束位置

    使用 while 循环检查当前盘子是否与下一个盘子连续。如果是,继续检查下一个盘子,直到不再连续。end 记录当前连续序列的结束位置。

  3. 判断序列长度

    如果连续序列的长度大于等于3(即 end - start >= 2),将其格式化为 start-end 的形式;否则,单独列出每个盘子。

  4. 拼接结果

    如果不是最后一个元素,添加逗号分隔符。然后继续遍历下一个盘子。

知识总结

  1. 数组遍历:通过 while 循环遍历数组,可以灵活地处理数组中的每个元素。
  2. 连续序列检测:通过检查当前元素与下一个元素的关系,可以找到连续的序列。
  3. 字符串拼接:使用 std::string 和 std::to_string 进行字符串拼接和格式化。
  4. 边界条件处理:在处理数组时,注意边界条件的处理,如最后一个元素的处理。

总结

通过以上步骤,我们可以有效地解决这个问题。关键在于遍历数组,找到连续的序列,并根据序列的长度进行不同的处理。代码实现中,我们使用了 while 循环和条件判断来实现这一逻辑。