求數組排列的範圍

問題描述:給定一個整數數組,將這個整數數組排列成一個整數,並且數組的每個元素都要用到,求所排列出的整數的範圍。

分析:這是一個很有意思的題目,初看好像是要求所有排列情況的最小值和最大值,當然這樣做也可以求出來,只不過時間複雜度過高,

        另外還有一個問題是大數問題,所排列成的數可能範圍很大,超過了基本數據類型所能表示的範圍,因此需要轉換爲字符串處理。

        下面詳細介紹解法:

        解法一:用排列法。也就是求出這個數組的全排列,然後求出這個排列的最小值和最大值。由於排列要用到遞歸實現,

                   遞歸一般消耗系統大量的時間和空間,因此該方法效率略低。

        解法二:直接求出排列的最大值和最小值。先介紹一種方法,對於兩個整數a和b,排列成一個整數後有兩種結果ab和ba,

                    這裏我們定義了一種新的大小規則,

                             如果ab>ba,我們就認爲a>b;

                             如果ab=ba,我們就認爲a=b;

                             如果ab<ba,我們就認爲a<b;

                   這不同於數學中的大小規則,爲了解決大數問題,先將整數數組轉化爲字符串數組,在進行比較。具體算法如下:

                   第一步:將整數數組轉換爲字符串數組。

                   第二步:將這個字符串數組按照我們新定義的大小規則進行排序。

                   第三步:將排序後的數組串連成一個字符串,這個字符串就是所要求的最小值。

                   第四步:將第三步字符串逆序就是所要求的最大值。

                   可以看出整個算法非常巧妙,避免了求排列的過程,整個算法的時間複雜度爲O(nlogn).

          具體的Java代碼如下,寫法比較通用,讀者可以很容易的轉化爲其他語言實現:

public class Main {
    public static String[] zuheminmax(int a[]){
    	String b[]=new String[a.length];
    	for(int i=0;i<a.length;i++)                       //數值轉換爲字符串
    		b[i]=new String(a[i]+"");
    	for(int i=0;i<b.length-1;i++)                     //按照自定義的規則排序
    		for(int j=i+1;j<b.length;j++)
    			if(compare(b[i],b[j]))
    			{	String t=b[i];
    	           b[i]=b[j];
    	           b[j]=t;
    			}
    	String minmax[]=new String[2];                     //用來存儲排列數的最小值和最大值
    	minmax[0]=new String("");
    	minmax[1]=new String("");
    	for(int i=0;i<b.length;i++)                       //將所有的數連接起來,組成最小值
    		minmax[0]+=b[i];
    	for(int i=0;i<b.length;i++)                       //將所有的數連接起來,組成最大值
    		minmax[1]=b[i]+minmax[1];
    	return minmax;
    }
    public static boolean compare(String a,String b){     //自定義比較規則
    	String ab=a+b;
    	String ba=b+a;
    	if(ab.compareTo(ba)>0)return true;
    	else return false;
    }
	public static void main(String[] args) {
		// TODO 自動生成的方法存根
       int a[]={12,10,5,6,9};
       String[] minmax=zuheminmax(a);
       System.out.println("最小值爲:"+minmax[0]);
       System.out.println("最大值爲:"+minmax[1]);
	}
}

輸出結果爲:

最小值爲:1012569
最大值爲:9651210


發佈了70 篇原創文章 · 獲贊 17 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章