LeetCode423题:Reconstruct Original Digits代码报Index out of Bound错误求助
问题背景
题目为LeetCode第423题:从英文重建数字,题目要求如下:
给定一个包含0-9数字英文乱序表示的字符串s,返回升序排列的数字。
我用Java编写的代码在多数输入下运行正常,但针对某一输入抛出**数组越界(Index out of Bound)**错误。
代码实现
public static String originalDigits(String s){ StringBuilder st = new StringBuilder(s); StringBuilder num = new StringBuilder(); while(st.length()!=0){ if (st.indexOf("z")!=-1){ num.append("0"); st.deleteCharAt(st.indexOf("z")); st.deleteCharAt(st.indexOf("e")); st.deleteCharAt(st.indexOf("r")); st.deleteCharAt(st.indexOf("o")); } if (st.indexOf("o")!=-1 && st.indexOf("n")!=-1){ num.append("1"); st.deleteCharAt(st.indexOf("o")); st.deleteCharAt(st.indexOf("n")); st.deleteCharAt(st.indexOf("e")); } if (st.indexOf("w")!=-1){ num.append("2"); st.deleteCharAt(st.indexOf("t")); st.deleteCharAt(st.indexOf("w")); st.deleteCharAt(st.indexOf("o")); } if (st.indexOf("h")!=-1 && st.indexOf("r")!=-1){ num.append("3"); st.deleteCharAt(st.indexOf("t")); st.deleteCharAt(st.indexOf("h")); st.deleteCharAt(st.indexOf("r")); st.deleteCharAt(st.indexOf("e")); st.deleteCharAt(st.indexOf("e")); } if (st.indexOf("u")!=-1){ num.append("4"); st.deleteCharAt(st.indexOf("f")); st.deleteCharAt(st.indexOf("o")); st.deleteCharAt(st.indexOf("u")); st.deleteCharAt(st.indexOf("r")); } if (st.indexOf("f")!=-1){ num.append("5"); st.deleteCharAt(st.indexOf("f")); st.deleteCharAt(st.indexOf("i")); st.deleteCharAt(st.indexOf("v")); st.deleteCharAt(st.indexOf("e")); } if (st.indexOf("x")!=-1){ num.append("6"); st.deleteCharAt(st.indexOf("s")); st.deleteCharAt(st.indexOf("i")); st.deleteCharAt(st.indexOf("x")); } if (st.indexOf("v")!=-1){ num.append("7"); st.deleteCharAt(st.indexOf("s")); st.deleteCharAt(st.indexOf("e")); st.deleteCharAt(st.indexOf("v")); st.deleteCharAt(st.indexOf("e")); st.deleteCharAt(st.indexOf("n")); } if (st.indexOf("g")!=-1){ num.append("8"); st.deleteCharAt(st.indexOf("e")); st.deleteCharAt(st.indexOf("i")); st.deleteCharAt(st.indexOf("g")); st.deleteCharAt(st.indexOf("h")); st.deleteCharAt(st.indexOf("t")); } if (st.indexOf("n")!=-1){ num.append("9"); st.deleteCharAt(st.indexOf("n")); st.deleteCharAt(st.indexOf("i")); st.deleteCharAt(st.indexOf("n")); st.deleteCharAt(st.indexOf("e")); } System.out.println(num); } String num1 = new String(num); return num1; }
错误原因分析
出现数组越界的核心问题有两点:
- 分支无互斥且重复操作字符串:所有判断都是
if而非else if,一次循环内可能触发多个分支,前面分支删除字符后,后面分支再查找字符时,目标字符可能已被删除,导致st.indexOf()返回-1,调用deleteCharAt(-1)直接抛出越界错误。 - 未校验删除字符的存在性:比如处理数字3时,要删除两个
e,但如果此时字符串中只剩一个e,第二次st.indexOf("e")会返回-1,触发越界;部分分支仅判断一个特征字符存在,就直接删除多个其他字符,未校验这些字符是否还存在。
解决方法
正确思路是通过字符统计+特征推导来实现,避免直接操作字符串的风险:
- 先统计每个字符的出现次数
- 利用数字英文的唯一特征字符确定部分数字的数量(比如0对应z、2对应w)
- 通过字符依赖关系推导剩余数字的数量(比如1的数量等于o的总数减去0、2、4的数量)
- 最后按升序拼接结果
修改后的代码如下:
public static String originalDigits(String s) { int[] charCount = new int[26]; // 统计所有字符出现次数 for (char c : s.toCharArray()) { charCount[c - 'a']++; } int[] numCount = new int[10]; // 先确定有唯一特征的数字数量 numCount[0] = charCount['z' - 'a']; numCount[2] = charCount['w' - 'a']; numCount[4] = charCount['u' - 'a']; numCount[6] = charCount['x' - 'a']; numCount[8] = charCount['g' - 'a']; // 通过字符依赖推导剩余数字数量 numCount[1] = charCount['o' - 'a'] - numCount[0] - numCount[2] - numCount[4]; numCount[3] = charCount['h' - 'a'] - numCount[8]; numCount[5] = charCount['f' - 'a'] - numCount[4]; numCount[7] = charCount['s' - 'a'] - numCount[6]; numCount[9] = charCount['i' - 'a'] - numCount[5] - numCount[6] - numCount[8]; // 按升序拼接结果 StringBuilder result = new StringBuilder(); for (int i = 0; i < 10; i++) { for (int j = 0; j < numCount[i]; j++) { result.append(i); } } return result.toString(); }
代码说明
- 字符统计避免了直接操作字符串的越界风险,所有计算基于统计值
- 唯一特征字符确定数字的逻辑简单直接,不会出现冲突
- 依赖推导逻辑严格对应数字英文的字符组成,确保结果准确
- 最后按0-9顺序拼接,自然满足题目要求的升序输出
内容的提问来源于stack exchange,提问作者Aryan Kaushik
相关产品推荐
相关产品推荐

