题目描述:

给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。

示例 1:

输入: [10,2]
输出: 210

示例 2:

输入: [3,30,34,5,9]
输出: 9534330

说明: 输出结果可能非常大,所以你需要返回一个字符串而不是整数。

要完成的函数:

string largestNumber(vector<int>& nums)

说明:

1、这道题给定一个vector,里面存放着int类型的非负整数,要求把这些非负整数拼起来,尽可能拼成一个最大的整数。

比如[10,2],可以拼成102,也可以拼成210,最大的整数就是210,那么返回210,以字符串的形式。

2、这道题关键在于判断,判断vector中的两个数谁大谁小,谁应该放在前面。

举个例子,比如[3,30,31,32,33,34,35,102,9,990],大家觉得应该怎么排序?

我们要尽可能让大的数字放在前面,所以首位肯定要放个大一点的,那么就是9了,其余的都是3,放在首位不合适。

那么9有两个,要放9还是990,这里要对这两个数的组合做个判断。

一种是9990,一种是9909,所以还是9-990这种组合。

那么接下来呢,9-990之后呢?3跟30比,一种是330,一种是303,所以还是3在30前面。

那3跟31比呢,一种是331,一种是313,还是3在31前面。

是不是所有短的数字都要放在前面?

其实不是的,比如3和34,一种是334,一种是343,还要考虑到后面这一位的情况。

所以最终排列下来,“降序”排列,是[9,990,35,34,33,3,32,31,30]。

按照这个vector从前往后添加到要返回的字符串中,就可以了。

这道题的关键在于判断谁在前谁在后,比较的方法也很普通,就是补齐两个字符串,比较谁大谁小。

当然在实际操作中,没有必要真的对字符串补齐,我们同样可以操作。

代码如下:(附详解)

    static bool cmp(int &a1,int &b1)//自定义一个比较函数,大的放前面
{
string a=to_string(a1),b=to_string(b1);//先把两个整数转化为字符串,操作起来比较方便
int s1=a.size(),s2=b.size();
if(s1<s2)//如果a短b长
{
for(int i=0;i<s1;i++)//在a的长度内比较
{
if(a[i]>b[i])//如果发现a中的某一位数值已经大于b中同一位的数值,比如4和39
return true;//那么比较到此结束,4要放在前面
else if(a[i]<b[i])//如果发现a中的某一位数值已经小于b中同一位的数值,比如4和61
return false;//那么比较到此结束,61要放在前面
}
for(int i=s1;i<s2;i++)//如果上面的比较没出结果,比如4和456这种情况,那么开始新的比较,直到到达第二个字符串的最后一位
{            //这个循环其实比较的是4和5,5和6,到达第二个字符串的最后一位就不比较了
if(b[i-s1]>b[i])//如果满足条件,那么a要放在前面
return true;
else if(b[i-s1]<b[i])//如果满足条件,那么b要放在前面
return false;
}
for(int i=0;i<s1;i++)//如果上面的比较没出结果,其实我们还有最后一位没有比较,6和4
{
if(a[i]<b[s2-s1+i])
return true;
else if(a[i]>b[s2-s1+i])
return false;
}
return false;//如果上述比较都没出结果,比如3和333,那么返回false,这里随便拼都可以
}
else if(s1>s2)//如果a长b短,一样的比较方式
{
for(int i=0;i<s2;i++)
{
if(a[i]<b[i])
return false;
else if(a[i]>b[i])
return true;
}
for(int i=s2;i<s1;i++)
{
if(a[i-s2]>a[i])
return false;
else if(a[i-s2]<a[i])
return true;
}
for(int i=0;i<s2;i++)
{
if(b[i]>a[s1-s2+i])
return true;
else if(b[i]<a[s1-s2+i])
return false;
}
return false;
}
else//如果两个一样长,那么直接逐位比较就可以了
{
for(int i=0;i<s1;i++)
{
if(a[i]>b[i])
return true;
else if(a[i]<b[i])
return false;
}
return false;
}
}
string largestNumber(vector<int>& nums)
{
sort(nums.begin(),nums.end(),cmp);//调用sort函数进行排序,排序准则是我们自定义的比较函数
string res;
for(auto i:nums)
res+=to_string(i);//不断地插入到字符串的末尾
if(res[0]=='0')return "0";//边界条件,如果第一位是0,那么说明后面即使有,也是全0,这时候我们只需要返回0就可以了了,而不是一长串的0
return res;
}

上述代码实测4ms,beats 99.85% of cpp submissions。

关于cmp函数,笔者在网上看到过一个简单的降序排列的版本,如下:

    bool cmp1(int &a,int &b)
{
return a>b;
}
int main()
{
vector<int>nums={1,2,3,4,5,6,7,8,9,10,11,12};
sort(nums.begin(),nums.end(),cmp1);
for(int i:nums)
cout<<i<<" ";
cout<<endl;
return 0;
}

上面的cmp1这个函数,笔者个人猜想其实是说,如果a>b,那么返回true,认为前面的数大于后面的数是正确的。

所以在进行排序的时候,如果前面的数大于后面的,那么经过cmp1这个函数,返回true,认为正确,所以不用更改。

如果前面的数小于后面的数,那么经过cmp1这个函数,返回false,认为错误,所以要换一下位置。

所以笔者就根据自己的猜想,设计了题解代码中的cmp函数,从结果来看,上述认识还是有一定可取之处的。

但上述仅为笔者个人的猜想,有可能是不完全的甚至有些错误,没有仔细地去查sort函数的参数,仅作为一个个人的认识。

leetcode-179-Largest Number(理解规则,自定义cmp函数进行排序)的更多相关文章

  1. leetcode 179. Largest Number 、剑指offer33 把数组排成最小的数

    这两个题几乎是一样的,只是leetcode的题是排成最大的数,剑指的题是排成最小的 179. Largest Number a.需要将数组的数转换成字符串,然后再根据大小排序,这里使用to_strin ...

  2. Java 特定规则排序-LeetCode 179 Largest Number

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  3. [LeetCode] 179. Largest Number 最大组合数

    Given a list of non negative integers, arrange them such that they form the largest number. Example ...

  4. JavaScript中sort方法的一个坑(leetcode 179. Largest Number)

    在做 Largest Number 这道题之前,我对 sort 方法的用法是非常自信的.我很清楚不传比较因子的排序会根据元素字典序(字符串的UNICODE码位点)来排,如果要根据大小排序,需要传入一个 ...

  5. [leetcode]179. Largest Number最大数

    Given a list of non negative integers, arrange them such that they form the largest number. Input: [ ...

  6. leetcode 179. Largest Number 求最大组合数 ---------- java

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  7. Java for LeetCode 179 Largest Number

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  8. [LeetCode] 179. Largest Number 解题思路

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  9. LeetCode 179 Largest Number 把数组排成最大的数

    Given a list of non negative integers, arrange them such that they form the largest number.For examp ...

随机推荐

  1. KbmMW 4.50.00 测试版发布

    We are happy to announce the release of kbmMW v. 4.50.00 Beta Professional and Enterprise Edition wi ...

  2. Django入门与实践-第16章:用户登录(完结)

    # myproject/settings.py LOGIN_REDIRECT_URL = 'home' EMAIL_BACKEND = 'django.core.mail.backends.conso ...

  3. Matlab 中以分数显示结果

    转http://www.blogbus.com/shijuanfeng-logs/234881647.html Matlab,计算得到的结果一般是小数形式. 但为了更精确表示,我们有时候需要用到分数形 ...

  4. cxf-rs 、spring 和 swagger 环境配置切换【github 有项目】

    环境切换的目的是 准生产和生产环境切换时,只修改一个文件就可以达到效果 在spring bean 文件中 配置: <bean class="cn.zno.common.context. ...

  5. Java(Android)线程池[转]

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

  6. Node.js是什么[译]

    当我向人们介绍Node.js的时候,一般会有两种反应:多数立刻表示“哦,这样啊”,另外的则会感到困惑. 如果你是第二种的话,我会试着这样解释node: 这是一个命令行工具.你可以下载一个tar包,然后 ...

  7. 基于MOD13A1的锡林郭勒草原近13年植被覆盖变化 分析

    内蒙古师范大学地理科学学院 内蒙古师范大学遥感与地理信息系统重点实验室 摘要:本研究以内蒙古锡林郭勒草原为研究区,基于MOD13A1遥感数据,经过遥感预处理,得到研究区2001-2013年共13年夏季 ...

  8. SharpMap源代码解析

    1. 简介 SharpMap是基于.net2.0的GIS系统.支持多种.NET开发语言(C# C++ 等).使用属性数据作为注记.符合OpenGIS的简单要素规范(OpenGIS Simple Fea ...

  9. hdu 5011 Nim+拿完分堆

    http://acm.hdu.edu.cn/showproblem.php?pid=5011 有N堆珠子,两个人轮流拿,最少拿一个,可以全拿,每次只能从一个堆里拿,不能从多堆同时拿:拿完之后该人还有一 ...

  10. mongodb 两小时入门

    传统的计算机应用大多使用关系型数据库来存储数据,比如大家可能熟悉的MySql, Sqlite等等,它的特点是数据以表格(table)的形式储存起来的.数据库由一张张排列整齐的表格构成,就好像一个Exc ...