题目描述
给定一个由非负整数组成的数组,你需要将这些数字按照某种顺序重新排列,使得它们组合成的数字最小。
例如,输入数组 [3, 30, 34, 5, 9],重新排列后的数字为 3033459。
解题思路
- 自定义排序规则:我们需要定义一个自定义的排序规则来比较两个数字组成的字符串。例如,对于数字 a 和 b,我们需要比较 ab 和 ba,取字典序较小的组合。
- 处理前导零:由于数字可能包含零,我们需要特别处理前导零的情况。如果某个数字是零,且它不是唯一的一个数字(即数组中还有其他数字),那么它应该排在非零数字之后,以避免产生前导零。
- 实现排序:根据自定义的规则对数组进行排序。
- 拼接结果:将排序后的数字拼接成最终的结果字符串。
Java 代码解析
import java.util.Arrays;
import java.util.Comparator;
public class Solution {
public String smallestNumber(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) {
if (a.equals("0") || b.equals("0")) {
if (!a.equals("0")) return -1;
if (!b.equals("0")) return 1;
}
String order1 = a + b;
String order2 = b + a;
return order1.compareTo(order2);
}
});
StringBuilder sb = new StringBuilder();
for (String num : strNums) {
sb.append(num);
}
// Remove leading zeros if the result is not just "0"
while (sb.length() > 1 && sb.charAt(0) == '0') {
sb.deleteCharAt(0);
}
return sb.toString();
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {3, 30, 34, 5, 9};
System.out.println(solution.smallestNumber(nums)); // Output: 3033459
}
}
C++ 代码解析
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
bool compare(const std::string &a, const std::string &b) {
if (a == "0" || b == "0") {
return !(a == "0") && b == "0";
}
std::string order1 = a + b;
std::string order2 = b + a;
return order1 < order2;
}
std::string smallestNumber(std::vector<int>& nums) {
std::vector<std::string> strNums;
for (int num : nums) {
strNums.push_back(std::to_string(num));
}
std::sort(strNums.begin(), strNums.end(), compare);
std::string result;
for (const std::string &num : strNums) {
result += num;
}
// Remove leading zeros if the result is not just "0"
size_t pos = result.find_first_not_of('0');
if (pos != std::string::npos) {
result = result.substr(pos);
} else if (!result.empty()) {
result = "0";
}
return result;
}
int main() {
std::vector<int> nums = {3, 30, 34, 5, 9};
std::cout << smallestNumber(nums) << std::endl; // Output: 3033459
return 0;
}
Python 代码解析
def smallest_number(nums):
def compare(a, b):
if a == '0' or b == '0':
return (a != '0') - (b != '0')
order1 = a + b
order2 = b + a
return (order1 < order2) - (order1 > order2)
str_nums = list(map(str, nums))
str_nums.sort(key=cmp_to_key(compare))
result = ''.join(str_nums)
# Remove leading zeros if the result is not just "0"
result = result.lstrip('0')
if not result:
result = '0'
return result
# Helper function for Python 2 compatibility (not needed in Python 3.x with functools.cmp_to_key)
# In Python 3, you can use `sorted` directly with `key=cmp_to_key(compare)`
from functools import cmp_to_key
nums = [3, 30, 34, 5, 9]
print(smallest_number(nums)) # Output: 3033459