题目:输入一个正整数数组,把数组里全部数字拼接起来排成一个数。打印能拼接出的全部数字中最小的一个。


样例说明:

比如输入数组{3。 32, 321},则扫描输出这3 个数字能排成的最小数字321323。

解题思路:

第一种:直观解法

先求出这个数组中全部数字的全排列,然后把每一个排列拼起来,最后求出拼起来的数字的最大值。

另外一种:排序解法

找到一个排序规则,数组依据这个规则排序之后能排成一个最小的数字。要确定排序规则,就要比較两个数字,也就是给出两个数字m 和n,我们须要确定一个规则推断m 和n 哪个应该排在前面。而不是只比較这两个数字的值哪个更大。

依据题目的要求,两个数字m 和n能拼接成数字m和m。

假设mn < nm,那么我们应该打印出m,也就是m 应该排在n 的前面,我们定义此时m 小于n:反之。假设nm < mn,我们定义n小于m。

假设mn=nm,m 等于n。在下文中,符号“<”、“>”及“=”表示常规意义的数值的大小关系,而文字“大于”、“小于”、“等于”表示我们新定义的大小关系。

接下来考虑怎么去拼接数字,即给出数字m和n。怎么得到数字m和m 并比較它们的大小。亘接用数值去计算不难办到。但须要考虑到一个潜在的问题就是m 和n 都在int 能表达的范围内,但把它们拼起来的数字m 和m 用int 表示就有可能溢出了。所以这还是一个隐形的大数问题。

一个很直观的解决大数问题的方法就是把数字转换成字符串。

另外,因为把数字m 和n 拼接起来得到m 和m,它们的位数肯定是同样的,因此比較它们的大小只须要依照字符串大小的比較规则就能够了。

本题採用另外一种方法实现

代码实现:

public class Test33 {

    /**
* 自己定义的排序比較器。实现算法说明的排序原理
*/
private static class MComparator implements Comparator<String> { @Override
public int compare(String o1, String o2) { if (o1 == null || o2 == null) {
throw new IllegalArgumentException("Arg should not be null");
} String s1 = o1 + o2;
String s2 = o2 + o1;
return s1.compareTo(s2);
}
} /**
* 高速排序算法
*
* @param array 待排序数组
* @param start 要排序的起始位置
* @param end 要排序的结束位置
* @param comparator 自己定义的比較器
*/
private static void quickSort(String[] array, int start, int end, Comparator<String> comparator) { if (start < end) {
String pivot = array[start];
int left = start;
int right = end;
while (start < end) {
while (start < end && comparator.compare(array[end], pivot) >= 0) {
end--;
} array[start] = array[end]; while (start < end && comparator.compare(array[start], pivot) <= 0) {
start++;
}
array[end] = array[start]; } array[start] = pivot; quickSort(array, left, start - 1, comparator);
quickSort(array, start + 1, end, comparator);
}
} /**
* 题目:输入一个正整数数组,把数组里全部数字拼接起来排成一个数,
* 打印能拼接出的全部数字中最小的一个。
* @param array 输入的数组
* @return 输出结果
*/
public static String printMinNumber(String[] array) { if (array == null || array.length < 1) {
throw new IllegalArgumentException("Array must contain value");
} MComparator comparator = new MComparator();
quickSort(array, 0, array.length - 1, comparator); StringBuilder builder = new StringBuilder(256);
for (String s : array) {
builder.append(s);
} return builder.toString();
} public static void main(String[] args) { String[] data = {"3", "5", "1", "4", "2"};
System.out.println(printMinNumber(data)); String[] data2 = {"3", "32", "321"};
System.out.println(printMinNumber(data2)); String[] data3 = {"3", "323", "32123"};
System.out.println(printMinNumber(data3)); String[] data4 = {"1", "11", "111"};
System.out.println(printMinNumber(data4)); String[] data5 = {"321"};
System.out.println(printMinNumber(data5));
}
}

执行结果:

【剑指Offer学习】【面试题33:把数组排成最小的数】的更多相关文章

  1. 《剑指offer》面试题45. 把数组排成最小的数

    问题描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.   示例 1: 输入: [10,2] 输出: "102" 示例 2: 输入: ...

  2. 剑指offer第32题:把数组排成最小的数及关于list.sort()和sorted( Iterable object )函数的相关知识

     * 解题思路:  * 先将整型数组转换成字符数组,然后将String数组排序,最后将排好序的字符串数组拼接出来.关键就是制定比较规则.  * 排序规则如下:  * 若ab > ba 则 a & ...

  3. 剑指offer三十二之把数组排成最小的数

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

  4. 【剑指offer】面试题 11. 旋转数组的最小数字

    面试题 11. 旋转数组的最小数字 题目描述 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...

  5. 剑指offer笔记面试题11----旋转数组的最小数字

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5 ...

  6. 《剑指offer》面试题11. 旋转数组的最小数字

    问题描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的 ...

  7. 剑指Offer:面试题33——把数组排成最小的数(java实现)(未完待续)

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

  8. 《剑指offer》面试题8—旋转数组的最小数字

    题目:把一个数组最开始的若干个元素搬到数组末尾我们称之为数组的旋转.要求:输入一个递增排序的数组的旋转,输出旋转数组中的最小数字.例如{3,4,5,1,2}是{1,2,3,4,5}的一个旋转,该数组的 ...

  9. 《剑指offer》面试题8 旋转数组的最小数字 Java版

    (找递增排序旋转数组中的最小数字) 书中方法:这种题目就是要寻找数组的特点,然后根据这个特点去写.旋转后的递增数组分为两段递增序列,我们找到中点,如果比第一个元素大,表示在第一段递增序列里,如果比第一 ...

  10. 【剑指Offer】面试题11. 旋转数组的最小数字

    题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个 ...

随机推荐

  1. OpenSSL使用3(基本原理及生成过程)(转)

    1. 基本原理 OpenSSL初接触的人恐怕最难的在于先理解各种概念 公钥/私钥/签名/验证签名/加密/解密/非对称加密 我们一般的加密是用一个密码加密文件,然后解密也用同样的密码.这很好理解,这个是 ...

  2. iOS7自定义back按钮和pop交互手势

    Clambake for iPhone有一个回退按钮在所有的导航条上.这是一个简单的没有文字箭头. 实现一个自定义按钮是简单的.类似这个设置controller 的navigationItem一个le ...

  3. iOS中后台运行

    iOS在升级到4.0以后就支持了多任务了.下文将详细介绍一下这个特性. 1.检查设备是否支持多任务 Apple出于性能的考虑,并不是所有的iOS设备升级到iOS4以后都支持多任务,比如iPhone 3 ...

  4. hdu2102 BFS

    这是一道BFS的搜索题目,只是搜索范围变为了三维.定义数组visit[x][y][z]来标记空间位置,x表示楼层,y和z表示相应楼层的平面坐标. #define _CRT_SECURE_NO_DEPR ...

  5. span设置padding无效

    <span style="display:inline-block;padding-top:10px">测试<span> 给span加属性 display: ...

  6. http://blog.csdn.net/LANGXINLEN/article/details/50421988

    GitHub上史上最全的Android开源项目分类汇总 今天在看博客的时候,无意中发现了 @Trinea在GitHub上的一个项目 Android开源项目分类汇总, 由于类容太多了,我没有一个个完整地 ...

  7. Linux学习之十三-vi和vim编辑器及其快捷键

    vi和vim编辑器及其快捷键 1.vi与vim区别 它们都是多模式编辑器,不同的是vim 是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面. vim的这些优势主要体现在以下几个方 ...

  8. 【FUN】——英文版面青年教育网站策划&GUI设计

    写在前面:这个教育网页一共分为四个页面,首页.课程.活动.空间.是我在学习网页设计与策划的时候作为知识应用练习做的,主要使用Photoshop软件设计构图,其中图片素材与部分灵感来源于网络. 一.网站 ...

  9. breakpoints &amp;&amp; lldb &#160;&amp;&amp; chisel 的使用

    Breakpoints BreakPoint分类 breakpoint也是有分类的.我这里的文章内大致按使用的方式分为了 Normal Breakpoint,Exception Breakpoint, ...

  10. 【AngularJS】Yeoman安装

    看不到PPT的请自行解决DNS污染问题.