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); } }
- 用
ArrayList<Integer>来存结果,因为邮箱数量不确定,动态数组比固定数组更灵活; - 遍历数组的1~totalCount索引(对应邮箱的编号,这样更直观);
- 每个位置如果状态是
true(也就是关闭状态),就把当前的索引(邮箱编号)添加到列表里; - 最后直接输出这个列表就行。
额外的优化小技巧
其实这个问题是经典的「灯泡开关问题」,有数学规律可循:最终关闭的邮箱编号都是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
相关产品推荐
相关产品推荐

