剑指offer:把数组排成最小的数(含数组的全排列)

题目描述

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

 

1.直接求解

最直接的方法,就是对数组中的数的组成做一个全排列,然后逐个遍历全排序的情况求取最小值,而全排列的时间复杂度是n!,

数组求全排列的方法:(递归)和字符串全排列的方法一样

实现:

import java.util.ArrayList;
import java.util.Collections;

public class Solution {
    ArrayList<String> list=new ArrayList<String>();
    public String PrintMinNumber(int [] numbers) {
        if(numbers==null||numbers.length==0){
            return "";
        }
        fun(numbers,0);
        Collections.sort(list);
        return list.get(0);
    }
    private void fun(int[] numbers,int i){
        if(i==numbers.length-1){
            StringBuffer sb=new StringBuffer();
            for(int item:numbers){
                sb.append(item);
            }
            if(!list.contains(sb.toString())){
                list.add(sb.toString());
            }
            return;
        }
        for(int j=i;j<numbers.length;j++){
            swap(numbers,i,j);
            fun(numbers,i+1);
            swap(numbers,i,j);
        }
    }
    private void swap(int[] numbers,int i,int j){
        int temp=numbers[i];
        numbers[i]=numbers[j];
        numbers[j]=temp;
    }
}

 

数字全排列代码:

import java.util.ArrayList;
import java.util.Arrays;

public class PermutationNum {
	ArrayList<String> ret=new ArrayList<>();
	private ArrayList<String> permutation(int[] num,int index){
		if(index==num.length-1){
			ret.add(Arrays.toString(num));
		}else{
			for(int i=index;i<num.length;i++){
				swap(num,index,i);
				permutation(num, index+1);
				swap(num,index,i);
			}
		}	
		return ret;
		
	}	
	private void swap(int[] num,int i,int j){
		int temp=num[i];
		num[i]=num[j];
		num[j]=temp;
	}
	

	public static void main(String[] args) {
		PermutationNum pn=new PermutationNum();
		int[] num={1,2,3};
		System.out.println(pn.permutation(num,0));
	}

}

2.利用java工具包,转换为字符串后排序输出。

自定义一种排序规则。

比如{3,32,321},

首先比较3,32的大小,它俩可以组成3 32和32 3,3 32>32 3,所以3>32;

接着比较32,321,它俩组成32 321和321 32,而32 321>321 32,所以32>321;

通过上面比较,可以确定321<32<3,

因此最小的数为321 32 3;

所以我们需要考虑的是定义一种新的排序方式:(两个数字拼接起来可能会导致溢出,因此需要采用字符串拼接的方式,打印并输出)

两个数字o1,o2,他们组成两种情况的字符串,str1=o1 o2,str2=o2 o1;

有上面举例情况可以看出,当str1>str2时,我们就认为o1>o2,由此进行排序。

利用java中的util工具包中的Arrays.sort()函数和Collections.sort()函数都可以实现对数组中的字符串两两排序的操作,我们只需要覆写其中的compare方法保证按我们定义的规则使数组进行排序即可。

  • Arrays.sort()方法:

 

  • compare方法

 

实现1:Collections.sort()

 

实现2:Arrays.sort()方法

 

python实现:

# -*- coding:utf-8 -*-
class Solution:
    def PrintMinNumber(self, numbers):
        # write code here
        if(numbers is None or len(numbers)==0):return ""
        numbers=list(map(str,numbers))
        numbers.sort(cmp=lambda x,y:cmp(x+y,y+x))
        return "".join(numbers).lstrip()

参考博客:

https://blog.csdn.net/tc_1337/article/details/81285596

https://www.cnblogs.com/hqbhonker/archive/2013/10/21/3380862.html

https://blog.csdn.net/u013309870/article/details/66530205

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值