叠盘子排序-题目解析| 豆包MarsCode AI刷题

46 阅读5分钟

摘要

本题涉及到一个关于盘子序号合并与输出的算法问题。题目要求根据给定的盘子序号数组,按照特定的规则进行合并,并以特定的格式输出结果。规则指出,如果盘子序号是连续递增的,并且连续序列的长度至少为3,则将这些盘子序号以start-end的格式进行合并;如果连续序列的长度小于3,则逐个输出盘子序号。

题目解析

问题描述

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

解题思路

题目理解

题目要求我们根据给定的盘子序号数组,将序号连续递增且长度至少为3的盘子序列进行合并,并以特定的格式输出。如果序列长度不足3,则单独列出每个盘子序号。

数据结构选择

  • 数组:题目已经给出了一个整数数组 plates,表示盘子的序号。我们可以直接使用这个数组进行操作。
  • StringBuilder:用于高效地拼接字符串,最终输出结果。

算法步骤

  1. 初始化

    • 使用 StringBuilder 来存储最终的输出结果。
    • 使用一个变量 start 来记录当前连续序列的起始位置。
  2. 遍历数组

    • 从第二个元素开始遍历数组,检查当前元素是否与前一个元素连续。
    • 如果当前元素与前一个元素不连续,或者已经遍历到最后一个元素,则判断当前连续序列的长度。
  3. 处理连续序列

    • 如果连续序列的长度大于等于3,则将起始编号和终止编号以 start-end 的格式添加到 StringBuilder 中。
    • 如果连续序列的长度小于3,则逐个添加盘子序号到 StringBuilder 中。
  4. 更新起始位置

    • 每次处理完一个连续序列后,更新 start 为当前位置,继续遍历。
  5. 输出结果

    • 最终将 StringBuilder 转换为字符串并返回。

代码详解

public class Main {
    public static String solution(int[] plates, int n) {
        StringBuilder result = new StringBuilder();
        int start = 0; // 记录当前连续序列的起始位置

        for (int i = 1; i <= n; i++) {
            // 如果当前盘子序号与前一个盘子序号的差值不为1,或者已经遍历到最后一个盘子
            if (i == n || plates[i] != plates[i - 1] + 1) {
                int length = i - start; // 计算当前连续序列的长度

                if (length >= 3) {
                    // 如果长度大于等于3,输出起始编号-终止编号
                    result.append(plates[start]).append("-").append(plates[i - 1]);
                } else {
                    // 否则,逐个输出盘子序号
                    for (int j = start; j < i; j++) {
                        result.append(plates[j]);
                        if (j < i - 1) {
                            result.append(",");
                        }
                    }
                }

                if (i < n) {
                    result.append(",");
                }

                start = i; // 更新起始位置
            }
        }

        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:用于存储最终的输出结果。
    • int start = 0:记录当前连续序列的起始位置。
  2. 遍历数组

    • for (int i = 1; i <= n; i++):从第二个元素开始遍历数组。
    • if (i == n || plates[i] != plates[i - 1] + 1):判断当前元素是否与前一个元素连续。
  3. 处理连续序列

    • int length = i - start:计算当前连续序列的长度。
    • if (length >= 3):如果长度大于等于3,则将起始编号和终止编号以 start-end 的格式添加到 StringBuilder 中。
    • else:否则,逐个添加盘子序号到 StringBuilder 中。
  4. 更新起始位置

    • start = i:每次处理完一个连续序列后,更新 start 为当前位置。
  5. 输出结果

    • return result.toString():将 StringBuilder 转换为字符串并返回。

总结

本题要求我们将一个整数数组中的盘子序号按照特定的规则进行合并和输出。规则是:如果盘子序号是连续递增的,并且连续序列的长度至少为3,则将这些盘子序号以start-end的格式合并输出;如果连续序列的长度小于3,则逐个输出盘子序号。

为了解决这个问题,我们采用了以下步骤:

初始化:

-   使用`StringBuilder`来高效地拼接最终的输出结果。
-   使用一个变量`start`来记录当前连续序列的起始位置。

遍历数组:

-   从第二个元素开始遍历数组,检查当前元素是否与前一个元素连续。
-   如果当前元素与前一个元素不连续,或者已经遍历到最后一个元素,则进行下一步处理。

处理连续序列:

-   计算当前连续序列的长度。
-   根据长度判断是合并输出还是逐个输出。
-   如果需要合并输出,则以`start-end`的格式添加到`StringBuilder`中。
-   如果逐个输出,则遍历当前连续序列,将每个盘子序号添加到`StringBuilder`中,并在序号之间添加逗号分隔符。

更新起始位置: - 每次处理完一个连续序列后,更新start为当前位置,继续遍历数组。 输出结果: - 将StringBuilder转换为字符串并返回作为最终结果。 通过这种方法,我们能够高效地处理并输出盘子序号的合并结果,满足题目的要求。 此外,我们还通过多个测试用例验证了代码的正确性,确保在不同情况下都能得到正确的输出结果。这种基于遍历和条件判断的方法在处理此类问题时具有通用性和高效性,可以应用于类似的数组处理任务中。