
将整数数组排列成能形成最大数值的字符串时,不能直接按数值大小排序,而应基于字符串拼接后的字典序比较来定制排序规则,避免整数溢出和逻辑错误。
将整数数组排列成能形成最大数值的字符串时,不能直接按数值大小排序,而应基于字符串拼接后的字典序比较来定制排序规则,避免整数溢出和逻辑错误。
在解决“将数组元素组合成最大数字”这一经典问题时,核心误区在于:误用数值比较代替字符串组合逻辑判断。原始代码试图将 arr[i] + arr[j] 和 arr[j] + arr[i] 转为 int 进行比较,但当数字较大(如 111311 和 1113)拼接后("111311111311"),远超 Integer.MAX_VALUE(2147483647),导致 NumberFormatException。
✅ 正确解法的关键在于:不转为整数,而是将两两组合结果作为字符串,用 String.compareTo() 比较字典序。因为 "9" > "82" 字典序成立,而 "9"+"82" = "982" 确实大于 "82"+"9" = "829" —— 这正是构造最大数所需的贪心依据。
以下为简洁、健壮、无溢出风险的实现(使用冒泡式自定义比较):
public class LargestNumber {
public static String largestNumber(int[] nums) {
// 转为字符串数组便于排序与拼接
String[] strs = new String[nums.length];
for (int i = 0; i b+a(字典序),则a应排在b前面
Arrays.sort(strs, (a, b) -> (b + a).compareTo(a + b));
// 边界处理:全零数组应返回 "0",而非 "000..."
if ("0".equals(strs[0])) {
return "0";
}
// 拼接结果
return String.join("", strs);
}
public static void main(String[] args) {
System.out.println(largestNumber(new int[]{54, 546, 548, 60})); // 输出: "6054854654"
System.out.println(largestNumber(new int[]{111311, 1113})); // 输出: "1113111311"
System.out.println(largestNumber(new int[]{0, 0})); // 输出: "0"
}
}
? 关键要点说明:
- ✅ 使用
String拼接与compareTo,完全规避整数溢出; - ✅ 排序器
(a, b) -> (b+a).compareTo(a+b)确保“高位优先”——即让更优前缀的字符串靠前; - ✅
Arrays.sort()基于Comparable或Comparator,时间复杂度优化至 O(n log n),远优于原始 O(n²) 冒泡; - ⚠️ 特殊处理全零场景:若最大元素(排序后首元素)是
"0",说明所有数都是 0,直接返回"0",防止输出"00...0"; - ? 进阶优化(如答案中提及的
Map+TreeMap)虽可去重计数,但对本题非必需——Arrays.sort已足够高效且代码清晰。
该方案兼顾正确性、性能与可读性,是工业级 Java 解决此类组合排序问题的标准实践。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











