题目描述:
给定一个nums数组由一些非负整数组成,现需要将他们进行排列并拼接,每个数不可拆分,使得最后的结果最大,返回值需要是string类型,否则可能会溢出
方法一:暴力破解法
题目分析:
由描述中分析可得,解决这个问题主要分为三步走:
- 排序(核心问题)
- 拼接
- 非负整数到string类型的转换
插入一个图片,可以一目了然。
解决办法:
首先从以上三个问题中最简单的说起:
1.非负整数到string类型的转换
最简单的办法:
std::string to_string(int value);
同时,还可以考虑C的库函数:
int sprintf( char *buffer, const char *format [, argument] ... );
(不过需要自行定义buffer)
2.拼接问题
对于string类型来说,最普遍的使用就是“+”,或者还可以考虑append()方法。
3.排序(重点)
根据描述中要得到最大的结果来看,首先我们想到的是越高位的值越大,这个最终的值就会越大。那么问题在于,排序中怎么按照高位从大到小的顺序排序,哎~是不是想到了sort()这个排序函数!
由于sort()函数默认为是升序排序,所以这里我们一定要编写排序规则函数compare使sort函数降序排序。
综上所述,目前我们的代码可以这样写:
class Solution { public: /** * 最大数 * @param nums int整型vector * @return string字符串 */ //排序规则函数 static bool compare(string& a, string& b) { return a + b > b + a; } string solve(vector<int>& nums) { if (nums.size() == 0) return nullptr; vector<string> strs; //将输入的非负整型数转化为string类型 for (auto c : nums) { strs.push_back(to_string(c)); } //排序 sort(strs.begin(), strs.end(), compare); //拼接 string MaxNum; for (auto c : strs) { MaxNum += c; } //类似["0","0"]的输入,输出是"0"而不是"00", //所以一定要在第一个元素为"0"时直接输出"0" if (MaxNum[0] == '0') return "0"; return MaxNum; } };
当然,不能使用如下的函数:
bool compare(string& a,string& b) { return a>b; }
因为:假设两个数207和88,使用这个排序规则函数,会将207放在88之前,但是显然88207>20788。
复杂度分析:
- 时间复杂度:两个for循环的时间复杂度都为 ,sort函数采用的是改进的快排,时间复杂度也为 ,所以本段代码的时间复杂度为 ;
- 空间复杂度:因为申请了一个存放转换后元素的vector,所以空间复杂度为 。
方法二:vector+桶排序
那么问题来了!如果想降低时间复杂度该怎么做呢,典型的就是用空间换取时间,我们可以使用桶排序的思想,定义一个vector数组,存放对应最高位的值。
动图演示如下:
代码如下:
class Solution { public: /** * 最大数 * @param nums int整型vector * @return string字符串 */ //排序规则函数 static bool compare(string& a, string& b) { return a + b > b + a; } string solve(vector<int>& nums) { if (nums.size() == 0) return nullptr; //使元素按照最高位的值分类 vector<string> strsArray[10]; for (auto& c : nums) { string temp = to_string(c); int index = temp[0] - '0'; strsArray[index].push_back(temp); } string MaxNum; for (int i = 9; i >= 0; i--) { //如果该vector没有元素直接跳过,如果只存在一个元素则不需排序 if (strsArray[i].size() == 0) continue; if (strsArray[i].size() > 1) sort(strsArray[i].begin(), strsArray[i].end(), compare); for (auto& c : strsArray[i]) MaxNum += c; } //类似["0","0"]的输入,输出是"0"而不是"00", //所以一定要在第一个元素为"0"时直接输出"0" if (MaxNum[0] == '0') { MaxNum = '0'; } return MaxNum; } };
复杂度分析:
- 时间复杂度:相比第一种算法而言,减少了最高位值不同元素的比较时间,如果输入的数据最高位均不同,那么此时的时间复杂度为,但是平均时间复杂度并没有改变,仍为 。
- 空间复杂度:修改后的代码看似多申请了很多vector,但是总的来说存储的元素的数量没有变,所以此时空间复杂度仍为为 。