剑指OFFER-把数组排成最小的数

剑指OFFER-把数组排成最小的数

  • Question
  • Solution
    • 重载比较函数

Question

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

Solution

重载比较函数

逻辑上,将数组中数字首位最小的放在前面,比如[1,22,333]中,首位分别是[1,2,3],因此最小数字会是1+22+333。当首位相同时我们就比较第二位的大小,如果没有第二位,就比较最后一位。比如[3,32,321],首位是都是‘3’,因此顺次比较第二位,又由于3没有第二位,因此比较它的最后一位‘3’,故第二轮比较应当是‘3’,‘2’,‘2’的比较,可以得到3是“最大”的那个,再继续比较32和321的第三位,32没有第三位因此用最后一位‘2’和321的‘1’比较,得到321比32小的结果。最终我们得出321<32<3,那么最小排序就会是321323。

对于上述解法,我们可以直接重载sort函数的比较函数(或者你也可以自己写一个sort函数,比如冒泡排序,对于[3,32]直接比较‘332’大还是‘323’大)。

时间复杂度:O(Nlog(N))
空间复杂度:O(N)

  • Python
class Solution:
    def PrintMinNumber(self, numbers):
        if not numbers:
            return '';
        str_nums = [str(n) for n in numbers]
        
        def compare(a,b):
            i = 0
            j = 0
            while i<len(a) or j<len(b):
                if i==len(a): 
                    i = len(a)-1
                if j==len(b): 
                    j = len(b)-1
                if a[i] < b[j]:
                    return -1
                elif a[i] > b[j]:
                    return 1
                else:
                    i +=1
                    j +=1
            return 0
        
        # Python3 取消了compare参数,需要额外的操作才能重载比较函数
        # from functools import cmp_to_key
        # str_nums = sorted(str_nums,key=cmp_to_key(compare))
        str_nums = sorted(str_nums, compare)

        ans = ''
        for n in str_nums:
            ans += n
        return int(ans)
  • C++
class Solution {
public:
	// 注意重载的比较函数如果卸载class里面,需要加static,因为sort是个全局函数,无法调用非静态函数
    static bool compare(const string a, const string b){
        int i = 0;
        int j = 0;
        while(i<a.length() || j<b.length()){
            if(i == a.length())
                i = a.length()-1;
            if(j == b.length())
                j = b.length()-1;
            if(a[i] < b[j])
                return true;
            else if (a[i] > b[j])
                return false;
            else{
                i++;
                j++;
            }
        }
        return true;
    }
    string PrintMinNumber(vector<int> numbers) {
        vector<string> str;
        for(int i=0; i<numbers.size(); i++)
            str.push_back(to_string(numbers[i]));
        
        sort(str.begin(), str.end(), compare);
        string ans;
        for(int i=0; i<numbers.size(); i++)
            ans += str[i];
        return ans;
    }
};

你可能感兴趣的:(剑指OFFER-把数组排成最小的数)