
你的代码试图通过条件判断和 HashSet 去重来生成无重复数字的三位数,但因循环内未重置状态、条件判断失效、以及对 Arrays.toString() 的误用,导致重复数字频出且集合去重失效。
你的代码试图通过条件判断和 hashset 去重来生成无重复数字的三位数,但因循环内未重置状态、条件判断失效、以及对 `arrays.tostring()` 的误用,导致重复数字频出且集合去重失效。
问题根源不在“算法思路”本身,而在于执行流程的结构性缺陷。我们逐层剖析:
? 1. rngNumString 状态未重置,错误持续累积
你在 while 循环内复用同一个数组 rngNumString = {"0","0","0"},但从未在每次新三位数生成前清空或重置它。更严重的是:
- 每次
for (index = 0; index 迭代中,你始终在修改<strong>同一个数组实例</strong>; - 当
index == 0时,无论之前值是什么,你都强制赋值(如"2"),于是rngNumString[0] = "2"; - 当
index == 1时,若随机数又是"2",条件!rngNumString[1].equals("2") && !rngNumString[0].equals("2")必然为 false(因为rngNumString[0]刚被设为"2"),所以跳过; - 但
rngNumString[1]仍保留初始值"0"—— 而你的后续逻辑却完全忽略"0"的存在,直接进入index == 2分支,并用新随机数覆盖rngNumString[2],最终得到类似["2", "0", "1"]—— 这根本不是合法的 1–4 数字组合,更谈不上“无重复”。
✅ 正确做法:每次生成新三位数前,应创建全新数组(如
new String[3])或显式重置所有元素为null/占位符,并确保每个位置都成功填入有效数字(1–4 且互异)。
? 2. 条件判断逻辑存在致命盲区
你的 else if 链只在满足条件时才赋值,不满足则保留旧值("0" 或上一轮残留值)。例如:
else if (index == 1 && (!rngNumString[index].equals(digit) && (!rngNumString[index - 1].equals(digit))))
rngNumString[index] = digit; // ❌ 不满足?rngNumString[1] 保持为 "0"
这意味着:只要某次随机失败,该位置就“卡住”,后续逻辑仍基于含 "0" 的脏数组运行,最终 Arrays.toString(rngNumString) 生成 "[2, 0, 1]" —— 这根本不是题目要求的三位数(且 "0" 不在 {1,2,3,4} 中)。
✅ 正确做法:使用
while循环重试单个位置,直到生成一个未在已填位置中出现的有效数字,而非依赖一次性的if判断。
? 3. HashSet 去重完全失效:Arrays.toString() 不是你想的那样
你调用:
Collections.addAll(randomSet, Arrays.toString(rngNumString));
Arrays.toString(new String[]{"1","2","3"}) 返回字符串 "[1, 2, 3]"(含空格和括号)。
而 Arrays.toString(new String[]{"1","2","3"}) 和 Arrays.toString(new String[]{"1","2","3"}) 确实相等,看似能去重 —— 但问题在于:
- 你是在
index == 2时才添加,但此时rngNumString极可能含"0"(如["2","0","1"]→"[2, 0, 1]"),这类非法组合也被加入 Set; - 更关键的是:你每轮
for循环中多次调用Collections.addAll(...),而randomSet是在while外声明的,因此它累积了所有历史尝试(包括大量含"0"的非法串); - 同时,
randomSetTest = new HashSet(randomSet)和randomList = new ArrayList(randomSetTest)在循环内反复创建,但randomList.size() 的终止条件却依赖这个不断被覆盖的列表 —— <strong>逻辑完全失控</strong>。
✅ 正确做法:仅在确认生成了一个合法的、无重复的三位数组合(如
["1","3","4"])后,才将其标准化为字符串(如"134")并加入 Set;且 Set 应在while外初始化,仅用于最终去重,而非参与生成过程。
? 总结:三个核心错误
| 错误类型 | 表现 | 后果 |
|---|---|---|
| 状态污染 | 复用未重置的 rngNumString 数组 |
残留 "0" 或旧值,破坏数字合法性 |
| 条件脆弱性 |
if 分支不覆盖所有情况,失败即跳过 |
位置填充不完整,生成非法组合 |
| 集合误用 | 对 "[1, 2, 3]" 去重,且在循环中反复重建集合 |
去重对象错误 + 控制流混乱,36 个结果实为随机采样噪声 |
要真正生成全部 24 个合法排列,推荐放弃随机重试,改用系统性全排列生成(如嵌套循环或递归);若坚持随机法,请重构为:每次生成→验证→去重→计数,且严格隔离状态。随机不是万能解药——尤其当解空间确定且较小时。











