程序员面试题精选100题(41)-把数组排成最小的数

以下文字摘自 http://zhedahht.blog.163.com/blog/static/25411174200952174133707/

题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32,  321},则输出这两个能排成的最小数字32132。请给出解决问题的算法,并证明该算法。

分析:这是096月份百度新鲜出炉的一道面试题,从这道题我们可以看出百度对应聘者在算法方面有很高的要求。

这道题其实是希望我们能找到一个排序规则,根据这个规则排出来的数组能排成一个最小的数字。要确定排序规则,就得比较两个数字,也就是给出两个数字mn,我们需要确定一个规则mn哪个更大,而不是仅仅只是比较这两个数字的数值哪个更大。

根据题目的要求,两个数字mn排成的数字mnnm,如果mn<nm,那么我们应该输出mn,也就是m应该排在n的前面,也就是m小于n;反之,如果nm<mnn小于m。如果mn==mnm等于n

接下来我们考虑怎么去拼接数字,即给出数字mn,怎么得到数字mnnm并比较它们的大小。直接用数值去计算不难办到,但需要考虑到的一个潜在问题是mn都在int能表达的范围内,但把它们拼起来的数字mnnm就不一定能用int表示了。所以我们需要解决大数问题。一个非常直观的方法就是把数字转换成字符串。

另外,由于把数字mn拼接起来得到的mnnm,它们所含有的数字的个数肯定是相同的。因此比较它们的大小只需要按照字符串大小的比较规则就可以了。

——————————————————————————————

代码实现其实并不需要向他实现的那么复杂。

其核心的代码是实现cmp函数。

代码如下

 
  
int front_cmp( const void * a, const void * b)
{
int first = * ( int * )a;
int second = * ( int * )b;
/*
while(first > 9)
first /= 10;
while(second > 9 )
second /= 10;
return first - second;
*/
static char pbuf1[ 21 ];
static char pbuf2[ 21 ];
sprintf(pbuf1,
" %d%d " ,first,second);
sprintf(pbuf2,
" %d%d " ,second,first);
return strcmp(pbuf1,pbuf2);

}

说明:1.static是为了避免多次栈中分配空间,分配21是由于max_int最大数只有10位数。

         2.sprintf函数是替代atoi的一个比较通用的方案。

再通过快速排序,即可得到答案。输出数组里面的数(连续输出,不要有空格即可)

经过测试,结果正确可行。

转载于:https://www.cnblogs.com/westfly/archive/2011/05/17/2048793.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值