描述
给定一个长度为n的数组nums,数组由一些非负整数组成,现需要将他们进行排列并拼接,每个数不可拆分,使得最后的结果最大,返回值需要是string类型,否则可能会溢出。
输入:
[2,20,23,4,8]
返回值:
“8423220”
进阶:时间复杂度O(nlogn) ,空间复杂度:O(n)
解题思路
方法一:类似冒泡排序
冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
void bubble_sort(T arr[], int len) {
int i, j;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
使用类似冒泡排序法,依次比较前后两个数,转化成string后相连的大小,排成由大到小的组合。
class Solution {
public:
string solve(vector<int>& nums) {
int size = nums.size();
for( int i=0;i<size;i++){
for(int j=1;j<size;j++){
if(to_string(nums[j])+to_string(nums[j-1])>to_string(nums[j-1])+to_string(nums[j])){
int temp = nums[j];
nums[j]=nums[j-1];
nums[j-1]=temp;
}
}
}
string res="";
for(int i=0;i<size;i++)
res+=to_string(nums[i]);
if(res[0]=='0') return "0";
return res;
}
};
时间复杂度:O(n2)冒泡排序两层循环
空间复杂度:O(1),没有使用额外空间
方法二:重载sort函数
字符串比较大小
java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码
String a=“a”,b=“b”;
System.out.println(a.compareto.b);
则输出-1;
若a=“a”,b="a"则输出0;
若a=“b”,b="a"则输出1;
单个字符这样比较,若字符串比较长呢??
若a=“ab”,b=“b”,则输出-1;
若a=“abcdef”,b="b"则输出-1;
也就是说,如果两个字符串首字母不同,则该方法返回首字母的asc码的差值;
如果首字母相同呢??
若a=“ab”,b=“a”,输出1;
若a=“abcdef”,b="a"输出5;
若a=“abcdef”,b="abc"输出3;
若a=“abcdef”,b="ace"输出-1;
即参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的asc码差值,如果两个字符串不一样长,可以参与比较的字符又完全一样,则返回两个字符串的长度差值
另写一个比较函数来重载sort的排序规则,规则是将两数转变成string后,相加比较大小。
class Solution {
public:
static bool comp(int s1,int s2){
return to_string(s1)+to_string(s2)>to_string(s2)+to_string(s1);
}
string solve(vector<int>& nums) {
sort(nums.begin(), nums.end(), comp);
string res = "";
for(int i = 0; i < nums.size(); i++) //遍历排序后的数组
res += to_string(nums[i]);
if(res[0] == '0') //当第一位数就是0时,整个最大也为0。去掉重复的0
return "0";
return res;
}
};
时间复杂度:O(nlog2n),sort函数属于快排,复杂度为O(n)
空间复杂度:O(1),没有使用额外的空间