题目链接

牛客网

题目描述

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

解题思路

可以看成是一个排序问题,在比较两个字符串 S1 和 S2 的大小时,应该比较的是 S1+S2 和 S2+S1 的大小,如果 S1+S2 < S2+S1,那么应该把 S1 排在前面,否则应该把 S2 排在前面。
45. 把数组排成最小的数 - 图1

  1. class Solution {
  2. public:
  3. string minNumber(vector<int>& nums) {
  4. vector<string> strs;
  5. string ans;
  6. for(int i=0;i<nums.size();i++){
  7. strs.push_back(to_string(nums[i]));//转为string
  8. }
  9. sort(strs.begin(),strs.end(),[](string &s1,string &s2 ){
  10. return s1+s2 < s2+s1;
  11. });// 匿名lambda表达式,自定义排序规则
  12. // s1+s2 < s2+s1时 s1在s2前面
  13. for(int i=0;i<strs.size();i++){
  14. ans+=strs[i];
  15. }
  16. return ans;
  17. }
  18. };
  19. // sort排序如下:
  20. for(int i = 0; i < numbers.length; i++){
  21. for(int j = i + 1; j < numbers.length; j++){
  22. pre = numbers[i] + "" + numbers[j]; //转换成字符串的形式
  23. last = numbers[j] + "" + numbers[i];
  24. if(pre.compareTo(last) > 0){ //比较组合之后的ab和ba
  25. temp = numbers[i];
  26. numbers[i] = numbers[j];
  27. numbers[j] = temp;
  28. }
  29. }
  30. sb.append(numbers[i]);
  31. }
  1. class Solution {
  2. public String minNumber(int[] nums) {
  3. Integer[] newNums = new Integer[nums.length];
  4. for(int i = 0; i < nums.length; ++i){
  5. newNums[i] = nums[i];
  6. }
  7. List<Integer> lst = Arrays.asList(newNums);
  8. Collections.sort(lst,(o1,o2)->{
  9. String x = String.valueOf(o1);
  10. String y = String.valueOf(o2);
  11. return (x+y).compareTo(y+x);
  12. });
  13. Iterator<Integer> it = lst.iterator();
  14. StringBuilder sb = new StringBuilder();
  15. while(it.hasNext()){
  16. sb.append(it.next());
  17. }
  18. return sb.toString();
  19. }
  20. }
  • 时间复杂度 O(NlogN) : N 为最终返回值的字符数量( strs 列表的长度 ≤N );使用快排或内置函数的平均时间复杂度为 O(NlogN) ,最差为 O(N^2)。
  • 空间复杂度 O(N) : 字符串列表 strs 占用线性大小的额外空间。