剑指 Offer 45. 把数组排成最小的数

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例 1:

输入: [10,2]
输出: “102”

示例 2:

输入: [3,30,34,5,9]
输出: “3033459”

思路:

这里需要知道一个规律,在字符串中,x+y>y+x 如果我们要字符串拼接小,我们就需要选择yx。
然后这里的排序我们使用快速排序。
正好使用这个题目让我又重新学习了一下快速排序。
快速排序的思想,设置两个哨兵,i和j,然后标志元素一般都是使用l元素。
然后 j找到第一个比l小的,之后i再找到第一个比l大的,然后二者交换。
直到i=j的时候,此处注意了,不能在i=j的时候在进入循环,这个时候肯定会出现越界问题。然后我们让l元素和i元素交换即可。
其实也可以用堆排序 小根堆,每次找到最小的,之后返回。

复杂度

时间复杂度:O(nlogn) —》快速排序的平均时间复杂度。
空间复杂度:O(n) -->保存str

class Solution {
    String []str;
    public String minNumber(int[] nums) {
        //选择排序进行求解
        str=new String[nums.length];
        for(int i=0;i<nums.length;i++)
        {
            str[i]=String.valueOf(nums[i]);
        }
        quicksort(0,str.length-1);
        //这里用到了StringBulid来提高速度。
        StringBuilder res=new StringBuilder();
        for(int i=0;i<str.length;i++){
            res.append(str[i]);
        }
        return res.toString();
    }
    public void quicksort(int l,int r){
       if(l>r)
           return ;
        int i=l,j=r;
        String x=str[l];
        //快速排序没有 =号 等号是结束的标志,要记住。
        while(i<j){
            while(i<j&&(str[j]+str[l]).compareTo(str[l]+str[j])>=0)
                j--;
            while(i<j&&(str[l]+str[i]).compareTo(str[i]+str[l])>=0)
                i++;
            String temp=str[i];
            str[i]=str[j];
            str[j]=temp;
        }
        str[l]=str[i];
        str[i]=x;
        quicksort(l,i-1);
        quicksort(i+1,r);
    }
    
}

方法二,使用堆来进行解决

class Solution {
    //堆排序
    public String minNumber(int[] nums) {
        String[] str=new String[nums.length];
        for(int i=0;i<nums.length;i++){
            str[i]=String.valueOf(nums[i]);
        }
        //首先建一个堆
        for(int i=nums.length/2-1;i>=0;i--){
            //其实就是上滑进行建堆
            bulidheap(str,i,nums.length);
        }
        //然后将最后一个元素和第0个元素交换
        for(int i=nums.length-1;i>=1;i--){
            swap(str,i,0);
            bulidheap(str,0,i);
        }
        StringBuilder res=new StringBuilder();
        for(int i=0;i<nums.length;i++){
            res.append(str[i]);
        }
        return res.toString();
    }
    public void bulidheap(String []str,int k,int len){
        int temp=k;
        while(true){
            if(k*2+2<len&&(str[k]+str[2*k+2]).compareTo((str[2*k+2]+str[k]))<=0)
                temp=k*2+2;
            if(k*2+1<len&&(str[temp]+str[2*k+1]).compareTo((str[2*k+1]+str[temp]))<=0)
                temp=k*2+1;
            if(temp==k)
                break;
            swap(str,temp,k);
            k=temp;
        }
    }
    public void swap(String []str,int x,int y){
        String temp=str[x];
        str[x]=str[y];
        str[y]=temp;
    }
      
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值