JZ32 把数组排成最小的数
题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路
我一开始想的是:
先将3,32组合好(332>323),所以前面两个的组合为(323),然后和后面再组合(323321>321323),所以结果为321323
这样是不对的,你不能把前面的组合好了再去和后面一个进行组合,虽然题目中的事例是可以的,但是再举个例子
:输入:[3,5,1,4,2]
照上面这么想的话结果就是:13542,1,3,5排好了但是2,4应该往里插入,这样就错了,结果应该是12345
为什么这样不对呢?
你比较了前面两个,只能说是这两个的相对位置确定了,但不代表他们就是这样的组合了,那应该把所有两两数字的相对位置都确定了才能确定最终的组合,这个就很类似我们的排序了,两两进行比较,但这个比较又不是谁小谁在前面
所以,这道题我们可以采用一种自定义排序的方法
如果:m+n>n+m====>就应该把n放在前面(这里姑且称为n比m小)
如果:m+n<n+m====>就应该把m放在前面(这里姑且称为m比n小)
可以想到sort函数里面可以自己定义比较器(这个比较难想到)
sort(.begin(),.end(),compare)
这个自定义比较器,有两种方法,一种是通过运算符重载,一种是通过函数
(1)运算符重载代码:
class myCompare { public: bool operator()(const string& str1, const string& str2) { return str1 + str2 < str2 + str1; } }; class Solution { public: string PrintMinNumber(vector<int> numbers) { vector<string> str_numbers; string str = ""; for (int i = 0; i < numbers.size(); i++) { str_numbers.push_back(to_string(numbers[i])); } sort(str_numbers.begin(), str_numbers.end(), myCompare()); for (int i = 0; i < numbers.size(); i++) { str += str_numbers[i]; } return str; } };
(2)函数定义比较器
需要注意:直接在sort中写函数名,定义的函数需要加static
class Solution { public: string PrintMinNumber(vector<int> numbers) { vector<string> strs; //先把数字全都替换成字符串放进一个数组(便于之后用sort进行排序) for(int i=0;i<numbers.size();i++) { strs.push_back(to_string(numbers[i])); } sort(strs.begin(),strs.end(),myCompare); //自定义排序方法 string result=""; for(int i=0;i<strs.size();i++) { result+=strs[i]; //将数组里的字符串拼接起来 } return result; } static bool myCompare(string str1,string str2) { return str1+str2<str2+str1; } };
还是记函数的方法吧!