【剑指offer】面试题33-把数组排成最小的数
2017-01-18 22:48
369 查看
题目描述:
输入一个正整数的数组,把数组里的所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。并给出算法的证明。比如输入数组,{3,32,321},则打印出这3个数字能排出的最小的数字是321323.题目分析:
这个题目最简单的做法也就是最容易想到的解法就是把数组中的数字进行全排列,求出最小的数。这样不是不可以,只是时间空间复杂度比较大。下边从一个简单的例子开始分析:
假如给定的数组是{3,32},可以拼接出的整数有两个:332和323,323就是小于332,所以,我们就把32排在3的前边,这样得到的数字是比较小的。试想,如果我们可以将一组数据按照上述比较的方式进行排序,然后依次打印出这个数组,得到的结果就是满足题意的结果。那么上述的比较方式是怎样的?
不是简单的比较就可以(3<32,3要排在32的前边吗?不一定的),3和32进行拼接,32和3进行拼接,完了之后比较两个结果的大小,我们是按照升序排列的。
为什么这样的排列就是可以得到正确的结果呢?
证明:(以下的证明参考文末的链接,这里感谢作者~)
可利用反证法,假设排成的最小数字为xxxxxx,并且至少存在一对字符串满足这个关系:a > b,但是在组成的数字中a排在b前面。根据a和b出现的位置,分三种情况考虑:
(1)xxxxab,用ba代替ab可以得到xxxxba,这个数字是小于xxxxab,与假设矛盾。因此排成的最小数字中,不存在上述假设的关系。
(2)abxxxx,用ba代替ab可以得到baxxxx,这个数字是小于abxxxx,与假设矛盾。因此排成的最小数字中,不存在上述假设的关系。
(3)axxxxb,这一步证明麻烦了一点。可以将中间部分看成一个整体ayb,则有ay < ya,yb < by成立。将ay和by表示成10进制数字形式,则有下述关系式,这里a,y,b的位数分别为n,m,k。
关系1: ay < ya => a * 10^m + y < y * 10^n + a => a * 10^m - a < y * 10^n - y => a( 10^m - 1)/( 10^n - 1) < y
关系2: yb < by => y * 10^k + b < b * 10^m + y => y * 10^k - y < b * 10^m - b => y < b( 10^m -1)/( 10^k -1)
关系3: a( 10^m - 1)/( 10^n - 1) < y < b( 10^m -1)/( 10^k -1) => a/( 10^n - 1)< b/( 10^k -1) => a*10^k - a < b * 10^n - b =>a*10^k + b < b * 10^n + a => a < b
这与假设a > b矛盾。因此排成的最小数字中,不存在上述假设的关系。
题目中要求每个数字都是正整数,但是2个数拼接起来有可能会大于整数的最大范围,所以这里也是涉及到一个大数据的问题。关于大数据问题,我们一般都是按照将数字转为字符串进行处理的,这里依然这样。
实现代码:
#include<iostream> using namespace std; #include<string> #include<algorithm> bool Compare(const string& str1,const string& str2) { string s1 = str1+str2; string s2 = str2+str1; return s1<s2; } void GetMin(int arr[],int n) { string* pArr = new string ;//定义string数组,存储每个数字对应的字符串 for(int i = 0; i < n; ++i) { char buffer[10]; _itoa(arr[i],buffer,10); pArr[i] = buffer; } sort(pArr,pArr+n,Compare); for(int i = 0; i < n; ++i) { cout<<pArr[i]; } cout<<endl; } int main() { //int arr[] = {32,321,1}; int arr[] = {3,32,321}; GetMin(arr,sizeof(arr)/sizeof(arr[0])); system("pause"); return 0; }
为了解决大数据的问题,这里采用c++的string来实现,也可以采用c语言的指针实现,这里只给出一种实现~
参考文档:http://blog.csdn.net/cxllyg/article/details/7659525
相关文章推荐
- 剑指Offer----面试题33:把数组排成最小的数
- 剑指Offer面试题33把数组排成最小的数,面试题34丑数
- 剑指offer-面试题33:把数组排成最小的数
- 剑指Offer面试题33(java版):把数组排成最小的数
- 剑指Offer:面试题33 把数组排成最小的数
- 【剑指Offer学习】【面试题33:把数组排成最小的数】
- 剑指offer--面试题33:把数组排成最小的数
- 剑指offer 面试题33—把数组排成最小的数
- 剑指Offer——面试题33:把数组排成最小的数
- 【剑指Offer学习】【面试题33:把数组排成最小的数】
- 【剑指Offer】面试题33:把数组排成最小的数
- 剑指offer 面试题33 数组组合的最小数
- 剑指offer-面试题33-把数组排成最小的数
- 剑指Offer之面试题33:把数组排成最小的数
- 剑指offer面试题33:把数组排成最小的数
- 【剑指offer】5.2时间效率——面试题33:把数组排成最小的数
- 剑指 offer——面试题8求旋转数组的最小值
- 【剑指Offer面试题】 九度OJ1504:把数组排成最小的数
- 剑指offer面试题8:旋转数组的最小数字
- 【练习笔记】剑指offer-面试题8 :旋转数组的最小数字