剑指Offer——把数组排成最小的数

题目描述

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

方法

输入为 vector<int> numbers, 输出为string。

可已将numbers中的int通过to_string函数变为string,然后对修改后的string进行排序(此时需要对两个字符串的比较函数进行修改),将多个字符串按照从小到大的顺序排好序后,将其拼接在一起,即为所需的输出。

修改后的字符串比较需要达到的效果:3>2,3>32,3>3332,3<4,3<34,3<3334,33<33334

主要问题在于如何做到3>32,3>3332,3<34,3<3334

可以看出,当开始的字符相同时,需要对后面的字符进行比较,如果str1比str2短,且str1从第一个字符到最后一个字符与str2中的前几个字符都是相同的,那么就需要看str2剩余的字符中,是否存在比str1[0]小的字符,如果存在,则str2小于str1,返回true,否则返回false。

具体代码如下:

// 比较函数
bool comp( string s1, string s2)
{
    int len1 = s1.size();
    int len2 = s2.size();
    int len = max( len1, len2 );
    for( int i=0;i<len;i++ )
    {
        if( i >= len1 )
        {
            if( s1[0] < s2[i] )
                return true;
            else
                continue;
        }
        else if( i >= len2 )
        {
            if( s1[i] < s2[0] )
                return true;
            else
                continue;
        }
        else if( s1[i] < s2[i] )
            return true;
        else if( s1[i] > s2[i] )
            return false;
    }

    return false;
}

class Solution {
public:
    string PrintMinNumber(vector<int> numbers) {
        string res;
        if( numbers.size()== 0 )
            return res;
        vector<string> input;
        for( int i=0;i<numbers.size();i++ )
            input.push_back( to_string(numbers[i]) ); //int转成string
        sort(input.begin(),input.end(),comp); //按照自定义的比较函数进行排序
        for( int i=0;i<input.size();i++ ) //将排序后的字符串拼接起来
            res += input[i];
        return res;
    }

};

NOTE:

  • sort的头文件为#include <algorithm>
  • 定义给sort函数使用的比较函数comp时,需要定义成静态函数或者全局函数,因为sort函数的第三个参数是具有两个形参的函数,而类函数会隐含的传递this指针,其实会多一个参数,导致sort函数运行报错

优化

上面使用的比价函数写起来十分复杂,可以进行改进。同样是对str1和str2进行比较,可以发现,如果将两个字符串进行拼接,可以得到str12=str1+str2,str21=str2+str1,将str12和str21进行比较,如果str12<str21,则str1<str2。

如str1=3, str2=3334,则str12=33334,str21=33343

class Solution {
public:
    // 需要是静态函数,或者全局函数
    static bool comp(const string &str1,const string &str2){
        string s1 = str1+str2;
        string s2 = str2+str1;
        return s1 < s2;
    }
    string PrintMinNumber(vector<int> numbers) {
        int size = numbers.size();
        vector<string> nums_str;
		
        //先转为字符串
        for(int i=0;i<size;i++){
            string s = to_string(numbers[i]);
            nums_str.push_back(s);
        }
	    // 使用 algorithm 库中的 sort函数
        sort(nums_str.begin(), nums_str.end(),comp);
        string ans = "";
        for(int i=0;i<size;i++){
            ans += nums_str[i];
        }
        return ans;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值