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

35 阅读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. 理解问题

    • 输入是一个整数数组 plates,表示盘子的序号。
    • 需要将这些盘子按照序号顺序叠放,每一堆盘子的序号都是连续递增的,并且至少包含3个盘子。
    • 如果某段序号不满足连续递增至少3个的条件,则单独列出。
  2. 数据结构选择

    • 使用一个列表来存储最终的结果字符串。
    • 使用两个指针来遍历数组,一个指针 start 指向当前段的起始位置,另一个指针 end 指向当前段的结束位置。
  3. 算法步骤

    • 初始化 startend 指针为数组的第一个元素。
    • 遍历数组,检查当前元素是否与前一个元素连续。
    • 如果连续,则 end 指针后移;如果不连续,则判断当前段的长度是否满足至少3个连续元素的条件。
    • 如果满足条件,则将这段序号加入结果列表,并更新 start 指针为当前元素;如果不满足条件,则将 startend-1 的元素逐个加入结果列表,并更新 start 指针为当前元素。
    • 最后,处理数组末尾的段。
  4. 输出结果

    • 将结果列表中的字符串用逗号连接起来,形成最终的输出字符串。

Java代码实现

public class Main {
    public static String solution(int[] plates, int n) {
        if (n == 0) return "";

        StringBuilder result = new StringBuilder();
        int start = 0;
        int end = 0;

        while (end < n) {
            // 找到连续递增的段
            while (end < n - 1 && plates[end + 1] == plates[end] + 1) {
                end++;
            }

            // 判断当前段是否满足至少3个连续元素的条件
            if (end - start >= 2) {
                if (result.length() > 0) result.append(",");
                result.append(plates[start]).append("-").append(plates[end]);
            } else {
                // 不满足条件,逐个添加
                for (int i = start; i <= end; i++) {
                    if (result.length() > 0) result.append(",");
                    result.append(plates[i]);
                }
            }

            // 更新指针
            end++;
            start = end;
        }

        return result.toString();
    }

    public static void main(String[] args) {
        // 测试样例
        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"));
    }
}

代码解释

  1. 初始化

    • StringBuilder result 用于存储最终的结果字符串。
    • startend 指针初始化为数组的第一个元素。
  2. 遍历数组

    • 使用 while 循环遍历数组,直到 end 指针到达数组末尾。
    • 在内部 while 循环中,找到连续递增的段,直到不连续为止。
  3. 判断段的长度

    • 如果当前段的长度 end - start >= 2,则将这段序号加入结果列表,并更新 start 指针为当前元素。
    • 如果不满足条件,则将 startend 的元素逐个加入结果列表,并更新 start 指针为当前元素。
  4. 输出结果

    • 将结果列表中的字符串用逗号连接起来,形成最终的输出字符串。