目录

裴先生
裴先生
发布于 2022-04-19 / 1 阅读
0
0

算法题:分班

原创

题目描述

幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友同班。请你帮忙把同班的小朋友找出来。

小朋友的编号为整数,与前一位小朋友同班用 Y 表示,不同班用 N 表示。

输入描述

  • 输入为一行字符串,由空格分开的小朋友编号和是否同班标志组成。
  • 例如:6/N 2/Y 3/N 4/Y
  • 其中,小朋友总数不超过 999,每个小朋友编号大于 0 且小于等于 999。
  • 不考虑输入格式错误问题。

输出描述

  • 输出为两行,每一行记录一个班小朋友的编号,编号用空格分开。
  • 排序规则:编号需要按照大小升序排列。
  • 行序规则:分班记录中第一个编号小的班级排在第一行。
  • 特殊情况:若只有一个班的小朋友,第二行为空行。若输入不符合要求(如人数超过999),则直接输出字符串 ERROR

示例 1

输入

1/N 2/Y 3/N 4/Y

输出

1 2
3 4

说明

  • 第1位小朋友是 1
  • 第2位小朋友是 2,标记 Y,表示和前面的 1 同班。
  • 第3位小朋友是 3,标记 N,表示和前面的 2 不同班(即属于另一个班)。
  • 第4位小朋友是 4,标记 Y,表示和前面的 3 同班。
  • 结果:1, 2 同班,3, 4 同班。
  • 班级 1, 2 的最小编号是 1,班级 3, 4 的最小编号是 3。因为 1 < 3,所以 1 2 在第一行。

💡 解题思路与代码优化

原始代码分析
原始代码逻辑基本正确,通过一个 classNum 变量追踪上一位小朋友所在的班级(A或B),从而判断当前小朋友归属。
但是存在以下可优化点:

  1. 字符串处理繁琐:使用 ArrayList<String> 存储编号,最后输出时通过 toString().replace(...) 去除方括号和逗号,这种方式不够优雅且效率较低。
  2. 逻辑冗余if ("A".equals(classNum))else 分支中的逻辑是对称的,可以简化。
  3. 健壮性:虽然题目说不考虑格式错误,但基本的边界检查(如空输入)是必要的。

优化方案

  1. 使用 List<Integer> 直接存储整数编号,利用 Collections.sort() 进行排序。
  2. 使用布尔值或简单的状态机逻辑来切换班级,减少字符串比较。
  3. 使用 StringBuilder 或 Java 8 的 String.join 来格式化输出。

优化后的 Java 代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

/**
 * 题目:幼儿园分班
 * 优化版解法
 */
public class DivideClassOptimized {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        if (!scanner.hasNextLine()) {
            return;
        }
        
        String line = scanner.nextLine().trim();
        // 处理空输入情况
        if (line.isEmpty()) {
            System.out.println("ERROR");
            return;
        }

        String[] inputs = line.split(" ");
        
        // 检查人数限制
        if (inputs.length > 999) {
            System.out.println("ERROR");
            return;
        }

        List<Integer> class1 = new ArrayList<>();
        List<Integer> class2 = new ArrayList<>();

        // 处理第一个小朋友,默认归入 class1
        String firstInput = inputs[0];
        if (!firstInput.contains("/")) {
             System.out.println("ERROR"); // 格式校验
             return;
        }
        
        int firstId = Integer.parseInt(firstInput.split("/")[0]);
        class1.add(firstId);
        
        // 记录上一位小朋友所在的班级,true代表class1,false代表class2
        boolean lastInClass1 = true;

        // 遍历剩余小朋友
        for (int i = 1; i < inputs.length; i++) {
            String[] parts = inputs[i].split("/");
            if (parts.length != 2) {
                System.out.println("ERROR");
                return;
            }
            
            int currentId = Integer.parseInt(parts[0]);
            String flag = parts[1];

            if ("Y".equals(flag)) {
                // 与前一位同班
                if (lastInClass1) {
                    class1.add(currentId);
                } else {
                    class2.add(currentId);
                }
                // lastInClass1 状态不变
            } else {
                // 与前一位不同班 (N)
                if (lastInClass1) {
                    class2.add(currentId);
                    lastInClass1 = false; // 状态翻转
                } else {
                    class1.add(currentId);
                    lastInClass1 = true;  // 状态翻转
                }
            }
        }

        // 排序
        Collections.sort(class1);
        Collections.sort(class2);

        // 确定输出顺序:最小元素小的班级排在第一行
        List<Integer> firstRow = class1;
        List<Integer> secondRow = class2;

        // 如果class2不为空,且(class1为空 或 class2的最小值 < class1的最小值)
        if (!class2.isEmpty() && (class1.isEmpty() || class2.get(0) < class1.get(0))) {
            firstRow = class2;
            secondRow = class1;
        }

        // 输出结果
        System.out.println(listToString(firstRow));
        System.out.println(listToString(secondRow));
    }

    // 辅助方法:将整数列表转换为空格分隔的字符串
    private static String listToString(List<Integer> list) {
        if (list == null || list.isEmpty()) {
            return "";
        }
        return list.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(" "));
    }
}

原创

版权声明:本博客原创文章,由 裴先生 2022年04月19日 发表。
转载说明:除特殊说明外本站文章皆由 CC BY-NC-SA 4.0 协议发布,转载须注明出处。


评论