算法小题之数组重排

题目描述

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

题目分析

先从题目出发,算一下给出的算例就可以发现规律,0-9当中越是小的数越应该放到最低位,数组中所有数最高位最小的应该放到前边作为高位,如果高位相同,比较下一位. 接下来从剩下的数当中依次执行这个规律,直观的想就是一个排序,但是这里面两数比较有点不太一样,关键是如何表达这种规律
可能你想到这很类似字符串的比较,有必要回顾下这个知识点:
s1与s2的大小取决于[1]:

1.如果 字符串1的第n位的ASCII码值 等于 字符串2的第n位的ASCII码值
则 继续比较下一位
2.如果 字符串1的第n位的ASCII码值 大于 字符串2的第n位的ASCII码值
则 输出结果:1,表示字符串1 > 字符串2;
3.如果 字符串1的第n位的ASCII码值 小于 字符串2的第n位的ASCII码值
则 输出结果:-1 表示字符串1 < 字符串2;
4.如果 每一位的ASCII码值都相等,而且长度相同,
则 输出结果:0 表示字符串1 == 字符串2;
5.如果 字符串1是字符串2的前m位,例如 abcd 与abcdef 比较,
则 字符串1<字符串2.

很明显第五条和我们想要的不太一样,实际上我们只需要比较的时候让字符串大小相同就可以,怎么办?拼起来:
如果$ab < ba$ , 那么$a <b$, 只需重载这个操作符然后排序,一切搞定

代码

class Solution {
public:
    string PrintMinNumber(vector<int> numbers) {
      string s = "";
 //quickSort(numbers, 0, numbers.size()-1);
	    sort(numbers.begin() , numbers.end() , smaller);
      for(auto i : numbers)
        s+= to_string(i);
      return s;
	} 
    bool smaller(const int &s1 ,const int &s2){
       string x =to_string(s1)+to_string(s2);
       string y =to_string(s2)+to_string(s1);
       return x<y;
    }
};

如果你想手敲一个快速排序的话也可以,顺便练练手,毕竟面试常考:

 void quickSort(vector<int> &a, int l , int r){
     int i = l, j = r;
     if(i < j){
	    int key = a[i];
       while(i < j){
        while(i<j && !smaller(a[j], key))
            j--;
          if(i < j)
            a[i++] = a[j];   
          while(i<j && smaller(a[i], key))
          	i++;
          if(i < j)
            a[j--] = a[i];
      }
	     a[i]= key;
       quickSort(a, l, i);
       quickSort(a, i+1 , r);
     }
       

[1]http://blog.csdn.net/yilin54/article/details/8224105

posted @ 2017-07-28 12:12  bzt007  阅读(140)  评论(0编辑  收藏  举报