
本文讲解如何将整数数组重新排列,使其连接后形成最大的数字,重点解决因整数溢出导致的 NumberFormatException,并提供高效、健壮的字符串比较排序方案。
本文讲解如何将整数数组重新排列,使其连接后形成最大的数字,重点解决因整数溢出导致的 `numberformatexception`,并提供高效、健壮的字符串比较排序方案。
在解决“拼接数组元素得到最大数值”问题时,直接按数值大小排序是错误的——例如 [111311, 1113] 中,111311 > 1113,但 "111311"+"1113" = "1113111113" 小于 "1113"+"111311" = "1113111311"。真正决定顺序的是两两拼接后的字典序大小:若 a+b > b+a(字符串比较),则 a 应排在 b 前面。
原始代码使用 Integer.parseInt(a) 将拼接字符串转为整数,但当数组元素较大(如 111311 和 1113)时,拼接结果 "111311111311" 远超 int 范围(约 21 亿),触发 NumberFormatException。根本解法是全程避免数值转换,仅用字符串比较:
public static void sortArray(int[] nums) {
// 冒泡排序(可替换为 Arrays.sort + 自定义 Comparator 提升性能)
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length; j++) {
String s1 = String.valueOf(nums[i]) + nums[j];
String s2 = String.valueOf(nums[j]) + nums[i];
if (s1.compareTo(s2) < 0) { // 注意:要使大者在前,所以 s1 < s2 时交换
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
}⚠️ 注意:上述冒泡实现中,if (s1.compareTo(s2) 表示当 <code>nums[i] 与 nums[j] 拼接后不如 nums[j] 在前时,交换二者位置,确保最终数组满足“高位优先取更大组合”的贪心策略。
更推荐使用 Java 标准库的 Arrays.sort 配合 Comparator,时间复杂度优化至 O(n log n),且代码简洁安全:
import java.util.*;
public static String largestNumber(int[] nums) {
// 转为字符串数组便于排序和拼接
String[] strs = new String[nums.length];
for (int i = 0; i < nums.length; i++) {
strs[i] = String.valueOf(nums[i]);
}
// 自定义比较器:按 a+b 与 b+a 的字典序降序排列
Arrays.sort(strs, (a, b) -> (b + a).compareTo(a + b));
// 边界处理:全零数组应返回 "0" 而非 "000..."
if ("0".equals(strs[0])) return "0";
return String.join("", strs);
}✅ 关键优势:
- 完全规避整数溢出风险;
- 利用字符串自然字典序比较,逻辑清晰;
-
Arrays.sort使用双轴快排,性能远优于 O(n²) 冒泡; - 包含
"0"边界检查,防止nums = [0,0]输出"00"。
调用示例:
int[] arr = {111311, 1113};
System.out.println(largestNumber(arr)); // 输出:"1113111311"
int[] arr2 = {54, 546, 548, 60};
System.out.println(largestNumber(arr2)); // 输出:"6054854654"总结:该问题本质是自定义排序问题,核心在于重定义元素间的大小关系——不是数值大小,而是拼接后的字符串字典序。坚持字符串操作、善用标准排序 API,并处理全零等边界情况,即可写出鲁棒、高效、可维护的解决方案。

















