一、题目描述
给定一组非负整数 nums
,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。
示例 1:
输入:
nums = [10,2]
输出:"210"
示例 2:
输入:
nums = [3,30,34,5,9]
输出:"9534330"
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 10^9
二、解题思路
- 将所有数字转换为字符串,因为我们需要根据字符串拼接的结果来比较大小。
- 对字符串数组进行排序。排序的规则是:对于任意两个字符串a和b,如果拼接结果
a+b
比b+a
大,则a应该排在b前面。 - 将排序后的字符串数组拼接成一个字符串。
- 需要处理特殊情况,即如果最高位是0(例如输入是[0,0]),则应该返回"0"。
三、具体代码
import java.util.Arrays;
import java.util.Comparator;
class Solution {
public String largestNumber(int[] nums) {
// 将整数数组转换为字符串数组
String[] strNums = new String[nums.length];
for (int i = 0; i < nums.length; i++) {
strNums[i] = String.valueOf(nums[i]);
}
// 自定义比较器,根据拼接后的结果进行排序
Arrays.sort(strNums, new Comparator<String>() {
@Override
public int compare(String a, String b) {
String order1 = a + b;
String order2 = b + a;
return order2.compareTo(order1); // 降序排序
}
});
// 如果排序后的第一个字符串是"0",则直接返回"0"
if ("0".equals(strNums[0])) {
return "0";
}
// 将排序后的字符串数组拼接成一个字符串
StringBuilder sb = new StringBuilder();
for (String s : strNums) {
sb.append(s);
}
return sb.toString();
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 转换整数数组为字符串数组:需要遍历整个整数数组,这个操作的时间复杂度是O(n),其中n是数组
nums
的长度。 - 对字符串数组进行排序:排序的时间复杂度取决于排序算法和比较操作的次数。在这个例子中,我们使用了Java的
Arrays.sort
方法,它通常使用的是经过优化的快速排序或归并排序,平均时间复杂度是O(n log n)。每次比较操作的时间复杂度是O(m),其中m是字符串的平均长度。因为每个字符串都要和其他所有字符串比较一次,所以总的时间复杂度是O(n^2 * m)。 - 拼接字符串数组:需要遍历整个字符串数组,这个操作的时间复杂度是O(n)。
综合上述操作,时间复杂度是O(n^2 * m),其中n是数组nums
的长度,m是字符串的平均长度。
2. 空间复杂度
- 字符串数组
strNums
:需要存储所有转换后的字符串,空间复杂度是O(n)。 StringBuilder
:在拼接字符串时,StringBuilder
会根据需要动态扩展其容量,但最终占用的空间不会超过所有字符串长度之和,因此空间复杂度是O(n)。
综合上述操作,空间复杂度是O(n),其中n是数组nums
的长度。
五、总结知识点
1. 数组和字符串转换:
- 使用
String.valueOf()
方法将整数转换为字符串。
2. 自定义比较器:
- 使用Java的
Comparator
接口来定义自定义比较逻辑。 - 重写
compare()
方法来指定两个字符串如何比较。
3. 数组的排序:
- 使用
Arrays.sort()
方法对字符串数组进行排序。 - 传递自定义比较器到
Arrays.sort()
方法中,以实现特定的排序规则。
4. 字符串比较:
- 使用
String
类的compareTo()
方法来比较两个字符串的大小。
5. 字符串拼接:
- 使用
StringBuilder
类来高效地拼接多个字符串。
6. 条件判断:
- 使用
if
语句来检查特定条件(例如,检查排序后的第一个字符串是否为"0")。
7. 循环结构:
- 使用
for
循环来遍历数组或集合。
8. 字符串和整数的比较:
- 使用
String
类的equals()
方法来比较字符串是否相等,而不是使用==
。
9. 异常处理:
- 在比较器中,隐式地处理了可能的
NullPointerException
(如果a
或b
为null
,则a + b
会抛出NullPointerException
,但在这个特定的场景中不会发生,因为数组是通过String.valueOf()
方法初始化的,不包含null
值)。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。