算法题19 把数组排成最小的数
2016-03-14 16:37
183 查看
题目
输入一个正整数数组,将他们连接起来排成一个数,输出所有排出的数字中最小的一个。例如:输入数组[32,321],输出所能排出的最小数为:32132.请给出该问题的算法。
分析
对于元素位置排列的问题,如a,b,我们希望找到一种排列规则,来确定我们所要得到的是a,b还是b,a. 题目要求得到所能排出的最小的数,那如a<b,则从常识来看ab<ba。这个比较规则到底正不正确呢?在剑指offer一书中有很好的证明
http://zhedahht.blog.163.com/blog/static/25411174200952174133707/
一个有效的比较规则需要三个条件:自反性、对称性、传递性。证明过程如下
1. 自反性。即a=a.
显然如aa=aa,则a=a
2. 对称性。即如果a>b,则b<a.
如果a<b,由规则ab<ba,显然ba>ab,即b>a.
3. 传递性。即如果a<b,b<c,则a<c
假设有条件a<b,b<c,则根据规则ab<ba,bc<cb. 假设a,b,c在高位时的10幂数分别为m,n,l
则a*10^m+b<b*10^n+a —》a*(10^m-1)<b*(10^n-1);
b*10^n+c<c*10^l+b —》b*(10^n-1)<c*(10^l-1);
因此有a*(10^m-1)<c*(10^l-1)
即a*10^m+c<c*10^l+a —》ac<ca
所以有a<c
我们也可以用分情况讨论的思路证明这个规则。对于数组中的a,b来说,排出的数字要么a在b前面,要么b在a前面。假设其他元素已经排成一个最小值XXX。有以下三种情况
/article/1361738.html
1. abXXX
显然如果ab<ba,abXXX<baXXX
2. XXXab
显然如果ab<ba,abXXX<baXXX
3. aXXXb
我们将中间部分看成c,则有acb.我们已知ab<ba,需证明acb<bca。假设a,c,b的位数分别是m,n,l
若acb>bca,则a*10^m+c*10^n+b>b*10^l+c*10^n+a ,两边同时减c*10^n —》a*10^m+b>b*10^l+a 即ab>ba和已知矛盾。由此可证acb<bca
代码
输入一个正整数数组,将他们连接起来排成一个数,输出所有排出的数字中最小的一个。例如:输入数组[32,321],输出所能排出的最小数为:32132.请给出该问题的算法。
分析
对于元素位置排列的问题,如a,b,我们希望找到一种排列规则,来确定我们所要得到的是a,b还是b,a. 题目要求得到所能排出的最小的数,那如a<b,则从常识来看ab<ba。这个比较规则到底正不正确呢?在剑指offer一书中有很好的证明
http://zhedahht.blog.163.com/blog/static/25411174200952174133707/
一个有效的比较规则需要三个条件:自反性、对称性、传递性。证明过程如下
1. 自反性。即a=a.
显然如aa=aa,则a=a
2. 对称性。即如果a>b,则b<a.
如果a<b,由规则ab<ba,显然ba>ab,即b>a.
3. 传递性。即如果a<b,b<c,则a<c
假设有条件a<b,b<c,则根据规则ab<ba,bc<cb. 假设a,b,c在高位时的10幂数分别为m,n,l
则a*10^m+b<b*10^n+a —》a*(10^m-1)<b*(10^n-1);
b*10^n+c<c*10^l+b —》b*(10^n-1)<c*(10^l-1);
因此有a*(10^m-1)<c*(10^l-1)
即a*10^m+c<c*10^l+a —》ac<ca
所以有a<c
我们也可以用分情况讨论的思路证明这个规则。对于数组中的a,b来说,排出的数字要么a在b前面,要么b在a前面。假设其他元素已经排成一个最小值XXX。有以下三种情况
/article/1361738.html
1. abXXX
显然如果ab<ba,abXXX<baXXX
2. XXXab
显然如果ab<ba,abXXX<baXXX
3. aXXXb
我们将中间部分看成c,则有acb.我们已知ab<ba,需证明acb<bca。假设a,c,b的位数分别是m,n,l
若acb>bca,则a*10^m+c*10^n+b>b*10^l+c*10^n+a ,两边同时减c*10^n —》a*10^m+b>b*10^l+a 即ab>ba和已知矛盾。由此可证acb<bca
代码
1 const int max_digits=10; 2 int catstr_max_len=2*max_digits+1; 3 char* catstr1=new char[catstr_max_len]; 4 char* catstr2=new char[catstr_max_len]; 5 int comp(const void* a,const void* b) 6 { 7 sprintf(catstr1,"%d%d",*(int*)a,*(int*)b); 8 9 sprintf(catstr2,"%d%d",*(int*)b,*(int*)a); 10 11 return strcmp(catstr1,catstr2); 12 } 13 void PrintMinNumber(int numbers[],int len) 14 { 15 if (!numbers||len<=0) 16 { 17 throw std::exception("Invalid input."); 18 } 19 20 //char* strnum=new char[len*max_digits]; 21 qsort(numbers,len,sizeof(int*),comp); 22 23 for (int i=0;i<len;i++) 24 { 25 cout<<numbers[i]; 26 } 27 cout<<endl; 28 }
相关文章推荐
- 算法题20 数值的整数次方
- 算法题21 打印1到最大的n位数
- 算法题22 树的镜像
- 算法题23 带min函数的栈
- 算法题24 二叉树的中序遍历之二叉搜索树转排序双向链表
- 算法题25 二叉树的后序遍历变形之二叉树中和为某一值的路径
- 将博客搬至CSDN
- MySql连接——内连接、外连接(左连接、右连接、全连接)
- 游戏中的 2D 可见性
- lintcode-medium-Best Time to Buy and Sell Stock II
- InitGoogleLogging坑爹
- C# zip压缩
- 数据仓库专题20-案例篇:电商领域数据主题域模型设计v0.1(改进意见征集中)
- HAproxy指南之haproxy配置详解1(理论篇)
- 内核启动错误:use vmalloc=<size> to increase size.
- 309.Best Time to Buy and Sell Stock with Cooldown
- Android设计模式系列(2)--SDK源码之观察者模式
- 浅谈MVP
- [BZOJ 3211] 花神游历各国
- 设计模式总结