给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。
示例 1:
输入:[10,2]
输出:210
示例 2:
输入:[3,30,34,5,9]
输出:9534330
解题思路:
归并排序。首先要明白,数组的整体大小能否达到最大,取决于任意的两个数字组合是否达到最大。如果任意的两个数字组合成的长数字都达到最大,那么整体必然是最大的。比较简单的方法是冒泡排序,检查比较两两之间合并,交换之后的两两合并的大小,如果交换后合并更大,说明这两个数需要交换。稍微复杂一些就是将冒泡排序改成归并排序,可以提速。
本题最主要的两个功能:
1. 获取一个非负整数的长度。
int getlength(int nums) {
int res = 1;
while (nums / 10 > 0) { res++; nums /= 10; }
return res;
}
2. 合并两个非负整数。由于整数发生了合并,也就意味着长度极可能超过32位,因此用long long 保险。
long long merge(int a, int size_a, int b, int size_b) {
long long res = a;
while (size_b > 0) { res *= 10; size_b--; }
res += b;
return res;
}
class Solution { public: string largestNumber(vector<int>& data) { nums = data; int size = nums.size(), i,j; length = vector<int>(size, 0); for (i = 1; i <= size; i++) { length[i-1] = getlength(nums[i - 1]); } merge_sort(0, size - 1); stringstream ss; string res,str; for (i = 1; i <= size; i++) { ss << nums[i - 1]; ss >> str; res += str; ss.clear(); } while (int(res.size()) >= 2 && res[0] == '0') res.erase(0, 1); return res; } void merge_sort(int first, int last) { if (first == last) return; if (first + 1 == last) { if (merge(nums[first], length[first], nums[last], length[last]) < merge(nums[last], length[last], nums[first], length[first])) { swap(nums[first], nums[last]); swap(length[first], length[last]); } } merge_sort(first, (first + last) / 2); merge_sort((first + last) / 2 + 1, last); int pos1 = first, pos2 = (first + last) / 2 + 1; vector<int> data,len; while (pos1 <= (first + last) / 2 || pos2 <= last) { if (pos1 > (first + last) / 2) { data.push_back(nums[pos2]); len.push_back(length[pos2]); pos2++; continue; } if (pos2 > last) { data.push_back(nums[pos1]); len.push_back(length[pos1]); pos1++; continue; } if (merge(nums[pos1], length[pos1], nums[pos2], length[pos2]) < merge(nums[pos2], length[pos2], nums[pos1], length[pos1])) { data.push_back(nums[pos2]); len.push_back(length[pos2]); pos2++; } else { data.push_back(nums[pos1]); len.push_back(length[pos1]); pos1++; } } for (int i = 1; i <= int(data.size()); i++) { nums[first + i - 1] = data[i - 1]; length[first + i - 1] = len[i - 1]; } } long long merge(int a, int size_a, int b, int size_b) { long long res = a; while (size_b > 0) { res *= 10; size_b--; } res += b; return res; } int getlength(int nums) { int res = 1; while (nums / 10 > 0) { res++; nums /= 10; } return res; } vector<int> nums; vector<int> length; }; |