题目
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路一
- 对数组中的数字进行全排列,依次拼接起来比较得到最小的值。
- 全排列的时间复杂度为O(n!)。
代码
class Solution {
private:
string resMinStr = "";
public:
string PrintMinNumber(vector<int> numbers) {
if ( !numbers.size() ) return "";
helper( numbers, 0 );
return resMinStr;
}
void helper( vector<int>& numbers, int start ) {
if ( numbers.size() == start ) {
if ( numbers[0] == 0 ) return;
string tempStr = "";
constuctStr( numbers, tempStr );
if ( resMinStr.empty() || lessThanMinStr(tempStr) )
resMinStr = tempStr;
return;
}
for ( int i = start; i < numbers.size(); ++i ) {
swap( numbers[i], numbers[start] );
helper( numbers, start+1 );
swap( numbers[i], numbers[start] );
}
return;
}
void swap( int& a, int& b ) {
int temp = a;
a = b;
b = temp;
return;
}
void constuctStr( vector<int>& nums, string& str ) {
for ( auto& n : nums )
str += to_string( n );
}
bool lessThanMinStr( string& str ) {
bool flag = false;
for ( int i = 0; i < str.size(); ++i ) {
if ( resMinStr[i] > str[i] ) {
flag = true;
break;
}
if ( resMinStr[i] < str[i] )
break;
}
return flag;
}
};
思路二
- 定义一种排序规则。如果有数字a、b,拼接的结果有ab和ba,如果ab>ba,则我们称a>b。
- 使用这种规则对数组进行排序,然后将数组中的元素拼接为字符串。
- 复杂度在于排序算法的复杂度。
- 我使用冒泡和快排两种。
冒泡
class Solution {
public:
string PrintMinNumber(vector<int> numbers) {
mySort( numbers );
string resStr = "";
constructStr( numbers, resStr );
return resStr;
}
void mySort( vector<int>& nums ) {
for ( int i = 0; i < nums.size(); ++i ) {
for ( int j = i+1; j < nums.size(); ++j ) {
if ( moreThan(nums[i], nums[j]) )
swap( nums[i], nums[j] );
}
}
return;
}
bool moreThan( int a, int b ) {
// 判断a是否大于b
bool flag = false;
string APlusB = to_string(a) + to_string(b);
string BPlusA = to_string(b) + to_string(a);
int i = 0;
while ( i < APlusB.size() ) {
if ( APlusB[i] > BPlusA[i] ) {
flag = true;
break;
}
if ( APlusB[i] < BPlusA[i] )
break;
++i;
}
return flag;
}
void swap( int& a, int& b ) {
int temp = a;
a = b;
b = temp;
return;
}
void constructStr( vector<int>& nums, string& resStr ) {
for ( auto& n : nums )
resStr += to_string(n);
return;
}
};
快排
只需把冒泡部分换为快排,替换的代码为
void mySort(vector<int> &nums, int lo, int hi) {
if (hi - lo < 1)
return;
int mid = partition(nums, lo, hi);
mySort(nums, lo, mid - 1);
mySort(nums, mid + 1, hi);
return;
}
int partition(vector<int> &nums, int lo, int hi) {
int index = lo + rand() % (hi - lo + 1);
swap(nums[lo], nums[index]);
int pivot = nums[lo];
while (lo < hi) {
while (lo < hi && lessEqualThan(pivot, nums[hi]))
--hi;
nums[lo] = nums[hi];
while (lo < hi && moreEqualThan(pivot, nums[lo]))
++lo;
nums[hi] = nums[lo];
}
nums[lo] = pivot;
return lo;
}
bool lessEqualThan(int &a, int &b) {
bool flag = true;
string APlusB = to_string(a) + to_string(b);
string BPlusA = to_string(b) + to_string(a);
int i = 0;
while (i < APlusB.size()) {
if (APlusB[i] > BPlusA[i]) {
flag = false;
break;
}
if (APlusB[i] < BPlusA[i])
break;
++i;
}
return flag;
}
bool moreEqualThan(int &a, int &b) {
bool flag = true;
string APlusB = to_string(a) + to_string(b);
string BPlusA = to_string(b) + to_string(a);
int i = 0;
while (i < APlusB.size()) {
if (APlusB[i] < BPlusA[i]) {
flag = false;
break;
}
if (APlusB[i] > BPlusA[i])
break;
++i;
}
return flag;
}