• 程序员面试题精选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的一个比较通用的方案。

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

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

  • 相关阅读:
    最近的几个坑
    最近对Allegro的几个总结
    sub drawing
    Allegro的几点小结
    产品量产的几个问题
    电源板问题的定位
    PCB学习
    servlet(6) 链接数据库
    servlet(5) HttpSession
    servlet(4)异常处理
  • 原文地址:https://www.cnblogs.com/westfly/p/2048793.html
Copyright © 2020-2023  润新知