剑指offer面试题45(java版):把数组排成最小的数

welcome to my blog

剑指offer面试题45(java版):把数组排成最小的数

题目描述

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

思路

  • 需要额外考虑的一个问题:m和n都在int型能表达的范围内,但它们拼接起来的数字mn和nm用int型表示就有可能溢出了,所以这还是一个隐形的大数问题
  • 两个数字a,b, 把a放在b的左边, 当且仅当str(a)+str(b) < str(b)+str(a)

笔记

  • 字符串String自身实现了Comparable接口中的compareTo()方法, 默认是自然排序
  • 如果我们需要自定义排序, 则需要继承Comparator接口并实现compare()方法
  • 使用Collections的静态方法sort()对List集合进行排序
    • Collections.sort(List list, Comparator<? super T> c)
        Collections.sort(al, new Comparator<Integer>(){
            public int compare(Integer t1, Integer t2){
                String str1 = ""+t1+t2;
                String str2 = ""+t2+t1;
                return str1.compareTo(str2);
            }
        });
  • 我开始弄错了, 想用Arrays.sort(T[] a, Comparator<? super T> c)对arr进行排序, 问题是:arr是int[]类型的, 但是泛型中不能用int!
  • 所以得用Collections.sort()对集合进行排序(可以将int[]转成Integer[])
  • ArrayList al = new ArrayList();可以添加int型, 添加进al后就变成Integer型了
第三次做, 巩固java基础, 字符串比较要用str.compareTo(); 通过字典序比较两个整数的大小时要保证两个整数的位数一样, 比如"323"与"332"按照字典序比较可以, 但是"323"与"33"按照字典序比较的结果就是错误的
class Solution {
    public String minNumber(int[] nums) {
        int n = nums.length;
        String[] strs = new String[n];
        for(int i=0; i<n; i++){
            strs[i] = String.valueOf(nums[i]);
        }
        Arrays.sort(strs, new Comparator<String>(){
            public int compare(String s1, String s2){
                //两个字符串长度一样, 此时字典序等于数值序
                return (s1+s2).compareTo(s2+s1);
            }
        });
        StringBuilder sb = new StringBuilder();
        for(String s : strs){
            sb.append(s);
        }
        return sb.toString();
    }
}
import java.util.Arrays;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        if(numbers==null||numbers.length==0)
            return ""; //返回形式和面试官商量
        Integer[] arr = new Integer[numbers.length];
        for(int i=0; i<arr.length; i++)
            arr[i] = numbers[i];
        Arrays.sort(arr, new Comparator<Integer>(){
            public int compare(Integer o1, Integer o2){
                //通过字典序比较两个整数的大小时要保证两个整数的位数一样
                //"323"与"332"按照字典序比较可以, 但是"323"与"33"按照字典序比较的结果就是错误的
                return (""+o1+o2).compareTo(""+o2+o1);
            }
        });
        //这里最好用StringBuilder, 节省字符串常量池空间
        String res="";
        for(int i=0; i<arr.length; i++)
            res+=arr[i];
        return res;
    }
}
第二次做,主要是要知道比较的定义要满足自反性,对称性,传递性;看上面的笔记
  • 巩固基础int[] → Integer[]; int → String; String → int

1 ) 自反性: x , y 的比较结果和 y , x 的比较结果相反。

2 ) 传递性: x > y , y > z ,则 x > z 。

3 ) 对称性: x = y ,则 x , z 比较结果和 y , z 比较结果相同

import java.util.Arrays;
import java.util.Comparator; 

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        if(numbers==null||numbers.length==0)
            return "";
        //
        Integer[] arr = new Integer[numbers.length];
        for(int i=0; i<arr.length; i++)
            arr[i] = numbers[i];
        Arrays.sort(arr, new Comparator<Integer>(){
            public int compare(Integer t1, Integer t2){
                String s1 = String.valueOf(t1);
                String s2 = String.valueOf(t2);
                return Integer.valueOf(s1+s2) - Integer.valueOf(s2+s1);
            }
        });
        String res = "";
        for(int i=0; i<arr.length; i++)
            res += String.valueOf(arr[i]);
        return res;
    }
}
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Collections;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        /*
        排序原则
        a在b的左边意味着: str(a)+str(b)<str(b)+str(a)
        注意证明过程中的传递性证明
        */
        ArrayList<Integer> al = new ArrayList<Integer>();
        for(int i=0; i<numbers.length; i++)
            al.add(numbers[i]);
        // sort(List<T> list, Comparator<? super T> c) 
        Collections.sort(al, new Comparator<Integer>(){
            public int compare(Integer t1, Integer t2){
                String str1 = ""+t1+t2;
                String str2 = ""+t2+t1;
                return str1.compareTo(str2);
            }
        });
        /*
        不能直接用return al.toString(); 因为AbstractCollection类的toString()方法如下:
        返回此 collection 的字符串表示形式。该字符串表示形式由 collection 元素的列表组成,
        这些元素按其迭代器返回的顺序排列,并用方括号 ( "[]") 括起来。
        相邻元素由字符 ", "(逗号加空格)分隔。通过 String.valueOf(Object) 可以将元素转换成字符串。
        */
        String res="";
        for(int i:al)
            res += Integer.toString(i);
        return res;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值