You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java邮箱布尔值翻转程序开发求助:数组筛选难题

搞定Java邮箱翻转问题:解决数组筛选剩余关闭邮箱的难题

嘿,我来帮你解决这个卡住的数组筛选环节,先理清楚整个问题的逻辑,再一步步给出代码方案。

问题回顾

用户输入数字作为邮箱总数,所有邮箱初始处于关闭状态(boolean类型值为true)。随后按规则翻转邮箱:先翻转每隔一个的邮箱,接着依次翻转第3个、第4个……直到仅翻转最后一个邮箱。最终需返回剩余关闭的邮箱,但目前卡在数组筛选环节,尚未完成结果返回功能。

先理清翻转规则

首先得明确你的翻转逻辑:

  • 第一步:翻转每隔一个的邮箱(也就是第2、4、6…个,步长为2)
  • 从第二步开始,依次以步长3、4…直到n,翻转对应倍数位置的邮箱(比如步长3时翻转第3、6、9…个,步长n时只翻转第n个)

初始状态是true(关闭),每翻转一次状态取反,最终我们要找出那些仍然是true的邮箱编号。

完整代码实现(包含筛选环节)

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MailboxManager {
    public static void main(String[] args) {
        // 获取用户输入的邮箱总数
        Scanner inputScanner = new Scanner(System.in);
        System.out.print("请输入邮箱总数:");
        int totalCount = inputScanner.nextInt();
        inputScanner.close();

        // 初始化邮箱状态:用1~totalCount的索引对应邮箱编号,true=关闭,false=打开
        boolean[] mailboxStatus = new boolean[totalCount + 1];
        for (int i = 1; i <= totalCount; i++) {
            mailboxStatus[i] = true; // 初始全关闭
        }

        // 执行第一步:翻转每隔一个的邮箱(步长2,从第2个开始)
        for (int i = 2; i <= totalCount; i += 2) {
            mailboxStatus[i] = !mailboxStatus[i];
        }

        // 执行后续翻转:步长从3到totalCount,翻转对应倍数的邮箱
        for (int step = 3; step <= totalCount; step++) {
            for (int i = step; i <= totalCount; i += step) {
                mailboxStatus[i] = !mailboxStatus[i];
            }
        }

        // 重点:筛选剩余关闭的邮箱(状态为true的)
        List<Integer> closedMailboxes = new ArrayList<>();
        for (int i = 1; i <= totalCount; i++) {
            if (mailboxStatus[i]) { // 状态为true代表关闭,把编号加入列表
                closedMailboxes.add(i);
            }
        }

        // 输出结果
        System.out.println("剩余关闭的邮箱编号:");
        System.out.println(closedMailboxes);
    }
}

你卡住的筛选环节详解

这段就是解决筛选问题的核心代码:

List<Integer> closedMailboxes = new ArrayList<>();
for (int i = 1; i <= totalCount; i++) {
    if (mailboxStatus[i]) {
        closedMailboxes.add(i);
    }
}
  1. 用ArrayList<Integer>来存结果,因为邮箱数量不确定,动态数组比固定数组更灵活;
  2. 遍历数组的1~totalCount索引(对应邮箱的编号,这样更直观);
  3. 每个位置如果状态是true(也就是关闭状态),就把当前的索引(邮箱编号)添加到列表里;
  4. 最后直接输出这个列表就行。

额外的优化小技巧

其实这个问题是经典的「灯泡开关问题」,有数学规律可循:最终关闭的邮箱编号都是1到n之间的完全平方数(比如n=10时,关闭的是1、4、9)。因为完全平方数的约数个数是奇数,会被翻转奇数次,回到初始的关闭状态;非完全平方数约数个数是偶数,翻转偶数次后变成打开状态。

如果追求效率,完全可以不用模拟翻转过程,直接生成这些平方数,代码更简洁,效率也更高:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MailboxManagerOpt {
    public static void main(String[] args) {
        Scanner inputScanner = new Scanner(System.in);
        System.out.print("请输入邮箱总数:");
        int totalCount = inputScanner.nextInt();
        inputScanner.close();

        List<Integer> closedMailboxes = new ArrayList<>();
        int num = 1;
        while (num * num <= totalCount) {
            closedMailboxes.add(num * num);
            num++;
        }

        System.out.println("剩余关闭的邮箱编号:");
        System.out.println(closedMailboxes);
    }
}

这样时间复杂度从O(n²)降到了O(√n),处理大数量邮箱的时候优势特别明显。

内容的提问来源于stack exchange,提问作者Aburito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:37:00