題目:
輸入一個正整數數組,把數組里所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字為321323。
思路:
1、全排列
求出數組中所有數字的全排列,然后把每個全排列拼起來,求出拼出來的數字的最大值。
2、定義新的排序規則
如果兩個數字m,n拼接成mn和nm,如果mn<nm,那么m應該排在n的前面,我們定義此時m小於n,如果mn=nm,我們定義m等於n。
可以考慮將數字轉成字符串,一來防止數字拼接時的溢出,二來字符串的拼接和比較容易實現。
由於把數字m和n拼接起來得到mn和nm,它們的位數一定是相同的,因此比較它們的大小只需按照字符串大小的比較規則即可。
代碼:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int g_MaxNumberLength=10;
char* g_strCombine1=new char[2*g_MaxNumberLength+1];
char* g_strCombine2=new char[2*g_MaxNumberLength+1];
int compare(const void* strNumber1,const void* strNumber2){
char* str1=(char*)strNumber1;
char* str2=(char*)strNumber2;
sprintf(g_strCombine1,"%s%s",str1,str2);
sprintf(g_strCombine2,"%s%s",str2,str1);
return strcmp(g_strCombine1,g_strCombine2);
}
void printMinNumber(int* numbers,int length){
if(numbers==NULL || length<=0)
return;
char** strNumbers=new char*[length];
for(int i=0;i<length;i++){
strNumbers[i]=new char[g_MaxNumberLength+1];
sprintf(strNumbers[i],"%d",numbers[i]);
}
qsort(strNumbers,length,sizeof(char*),compare);
for(int i=0;i<length;i++)
printf("%s",strNumbers[i]);
printf("\n");
for(int i=0;i<length;i++)
delete[] strNumbers[i];
delete[] strNumbers;
}
int main()
{
int numbers[]={3,32,321};
int length=sizeof(numbers)/sizeof(numbers[0]);
printMinNumber(numbers,length);
return 0;
}
在線測試OJ:
http://www.nowcoder.com/books/coding-interviews/8fecd3f8ba334add803bf2a06af1b993?rp=2
AC代碼:
class Solution {
public:
static bool compare(int a,int b){
string strNum1=to_string(a);
string strNum2=to_string(b);
return (strNum1+strNum2)<(strNum2+strNum1);
}
string PrintMinNumber(vector<int> numbers) {
string result;
if(numbers.empty())
return result;
sort(numbers.begin(),numbers.end(),compare);
for(unsigned int i=0;i<numbers.size();i++)
result+=to_string(numbers[i]);
return result;
}
};
