剑指offer面试题目:把数组排成最小的数

来源:互联网 发布:管材销售 知乎 编辑:程序博客网 时间:2024/05/20 14:23

题目

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
输入
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数。
输入的第二行包括m个正整数,其中每个正整数不超过10000000。
输出
对应每个测试案例,
输出m个数字能排成的最小数字。

  • 样例输入:
  • 3
    23 13 6
    2
    23456 56

  • 样例输出:
  • 13236
    2345656


    思路

  • 要求把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个,直接想到的是先求出这个数组中所有数字的全排列,然后把每个排列拼起来,最后求出拼起来的数字的最小值。但是效率较低,考虑新的改进算法,希望能找到一个排序规则,数组根据这个排序规则能排成一个最小的数字。要确定排序规则,就要比较两个数字,也就是给出两个数字m和n,需要一个规则判断m和n那个应该排在前面,而不是仅仅比较这两个数字的值那个大。
  • 两个数字m和n能拼接成数字mn和nm。如果mn,那么我们应该打印mn,也就是m应该排在n前面,定义此时m小于n;如果mn>nm,那么我们应该打印nm,也就是n应该排在m前面,定义此时m大于n;如果mn=nm,定义此时m等于n。
  • 但是我们要想到拼接数字时有一个隐形的大数问题。把两个int型的整数拼接起来得到的数字可能会超出int型数字能够表达的范围,从而导致溢出。通常非常直观的解决大数问题的方法就是把数字转换成字符串。而且把数字m和n拼接起来得到mn和nm,他们的位数一定是相同的,因此比较他们的大小只需要按照字符串大小的比较规则就可以了。

  • 代码

    #include<iostream>  #include<algorithm>  #include<string>  #include<sstream>  using namespace std;  int compare1(string str1,string str2)//自定义的比较大小的函数,str1 "小"的话,返回true  {      string tmp1 = str1.append(str2);      string tmp2 = str2.append(str1);      if(tmp1.compare(tmp2)<0)//          return true;      return false;  }  int main()  {         int num[] = {332,41,322,32,414,4};      int len = sizeof(num)/sizeof(int);      cout<<"len = "<<len<<endl;      string *word = new string[len];      stringstream sst;      for(int i=0;i<len;i++)//讲int整数转化成字符串      {          sst<<num[i];          sst>>word[i];          sst.clear();      }      cout<<endl;      sort(word,word+len,compare1);//利用泛型算法排序      for(int i=0;i<len;i++)      {          cout<<word[i];      }      getchar();      return 0;  }  
    原创粉丝点击