1. 程式人生 > >貪心算法----字典序最小問題

貪心算法----字典序最小問題

== class 分析 build 文字 bst stringbu 技巧 end

題目:

  字典序最小問題,給一個定長為N的字符串S,構造一個字符串T,長度也為N。起初,T是一個空串,隨後反復進行下列任意操作:1. 從S的頭部刪除一個字符,加到T的尾部 2. 從S的尾部刪除一個字符,加到T的尾部。目標是最後生成的字符串T的字典序盡可能小。1≤N≤2000。字符串S只包含大寫英文字母。

  輸入:字符串S
  輸出:字符串T。要求每80個字符換行輸出

  樣例輸入:

6
A
C
D
B
C
B

  樣例輸出:

ABCBCD

  思路分析:從題目上就可以得出這道題的解法就是循環比較首尾元素的字典序,難點就是假如兩個字符相同時該如何處理,例如字符串"ACDBCB",那麽第一次循環肯定是先把A加進來,然後把B加進來,下一次判斷的時候發現頭尾都是"C"那麽繼續往下看頭尾兩個字符發現B的字典序小於D那麽肯定是先加上尾部的這個C的字符的,然後把B加進來,把C加進來,把D進來,最後形成了字典序最小的字符串"ABCBCD"。這裏有一個重要的解題技巧,除了用雙指針比較字符串的首尾元素

之外,還可以用到翻轉字符串的方法去解這道題,具體代碼如下:

 1 public class 字典序最小問題 {
 2 
 3     public static void main(String[] args) {
 4         Scanner sc = new Scanner(System.in);
 5         int N = sc.nextInt();
 6         StringBuilder ss = new StringBuilder();
 7         for (int i = 0; i < N; i++) {
 8             ss.append(sc.next());
9 } 10 // String s = sc.nextLine(); 11 f(ss.toString()); 12 13 } 14 15 private static void f(String s) { 16 String s1 = new StringBuilder(s).reverse().toString(); 17 int N = s.length(); 18 StringBuilder rs = new StringBuilder(); 19 int
cnt = 0; 20 while (rs.length() < N) { 21 if (s.compareTo(s1) <= 0) { 22 rs.append(s.charAt(0)); 23 s = s.substring(1); 24 } else { 25 rs.append(s1.charAt(0)); 26 s1 = s1.substring(1); 27 } 28 // 字符滿80個就換行 29 if (rs.length() % 80 == 0) { 30 System.out.println(rs.substring(cnt * 80, (cnt + 1) * 80)); 31 cnt++; 32 } 33 } 34 // 余數部分 35 if (rs.length() > cnt * 80) { 36 System.out.println(rs.substring(cnt * 80)); 37 } 38 } 39 40 }

  結果:

    技術分享圖片

貪心算法----字典序最小問題