字符串低位优先排序真的只能排序字符串相同的字符么?

最近在刷剑指Offer上的题时遇到一题:

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

突然想到使用LSD算法,

 1 package com.roysatm.niuke;
 2 
 3 
 4 /**
 5  * Created by roysatm on 2016/5/30.
 6  */
 7 public class SolutionPrintMinNumber {
 8 
 9     /**
10      * 采用LSD(低位优先排序)思想,可以说能把高位优先排序取代。
11      * 基本是O(n)时间复杂度完成,没有使用任何java集合框架
12      * 代码可能不是最优,特别是空间复杂度方面
13      */
14     public String PrintMinNumber(int[] numbers) {
15 
16         if (numbers == null || numbers.length == 0) {
17             return "";
18         }
19 
20         String[] str = new String[numbers.length];
21         int w = 0;
22         //将int数组转成string数组
23         for (int i = 0; i < numbers.length; i++) {
24             str[i] = numbers[i] + "";
25         }
26         //计算出str数组中长度最长的字符串长度
27         for (int i = 0; i < str.length; i++) {
28             if (str[i].length() > w) {
29                 w = str[i].length();
30             }
31         }
32 
33         StringBuilder sb = new StringBuilder();
34 
35         String[] array = PrintMinNumber(str, w);
36         //将String数组转换成String字符串
37         for (int i = 0; i < array.length; i++) {
38             sb.append(array[i]);
39         }
40         return sb.toString();
41     }
42 
43     public String[] PrintMinNumber(String[] str, int w) {
44 
45         /**
46          * 低位优先排序,主要看点是getCharAt(String s, int index)函数的变化
47          由于getCharAt(String s, int index)函数的改变,LSD可以排长度不同的字符串
48          * **/
49 
50         int R = 256;
51         int N = str.length;
52         String[] aux = new String[N];
53 
54         for (int i = w - 1; i >= 0; i--) {
55 
56             int[] count = new int[R + 1];
57 
58             for (int j = 0; j < N; j++) {
59                 count[getCharAt(str[j], i) + 1]++;
60             }
61 
62             for (int j = 0; j < R; j++) {
63                 count[j + 1] += count[j];
64             }
65 
66             for (int j = 0; j < N; j++) {
67                 aux[count[getCharAt(str[j], i)]++] = str[j];
68             }
69 
70             for (int j = 0; j < N; j++) {
71                 str[j] = aux[j];
72             }
73         }
74 
75         return str;
76     }
77 
78     private char getCharAt(String s, int index) {
79 
80         if (s.length() <= index) {
81             return s.charAt(s.length() - 1);
82         } else {
83             return s.charAt(index);
84         }
85     }
86 
87     public static void main(String[] args) {
88         int[] a = {12, 2, 34, 13, 54};
89         SolutionPrintMinNumber spm = new SolutionPrintMinNumber();
90         String str = spm.PrintMinNumber(a);
91         System.out.print(str + " ");
92 
93     }
94 }

以上算法是LSD排序算法升级版,不仅能排序字符串长度相同的数组,还能像高位优先一样排序字符串不同的数组。

下次有时间再详细写写.......

posted @ 2016-06-24 18:16  roysatm  阅读(304)  评论(0编辑  收藏  举报