《劍指offer》面試題28:字符串的排列(牛客網版本) java


題目描述

輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。 

輸入描述: 輸入一個字符串,長度不超過9(可能有字符重復),字符只包括大小寫字母。

這里尤其需要注意2點:1.所有組合不能重復,比如輸入"aa",  那么輸出的結果應當是“aa” ; 2. 輸出結果按字典序排序

如果用《劍指offer》上的方法,顯然這兩點都不能滿足,比如輸入"abc",輸出結果為:"abc" "acb" "bac" "bca"  "cba" "cab" ,如果輸入"aa",輸出解過為"aa" "aa" 。顯然,這兩種結果都是有問題的。

下面是《劍指offer》版本的代碼:

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 public class Solution {
 4     private List<String> list = new ArrayList<>();
 5     private StringBuffer buffer;
 6     public ArrayList<String> Permutation(String str) {
 7         if(str==null||str.length()==0) return (ArrayList<String>) list;
 8         buffer = new StringBuffer(str);
 9         PermutationCore(0);
10         return (ArrayList<String>) list;
11     }
12     public void PermutationCore(int begin) {
13         if(begin==buffer.length()-1){
14             list.add(buffer.toString());
15         }
16         for(int i = begin;i<buffer.length();i++){
17             swap(begin,i);
18             PermutationCore(begin+1);
19             swap(begin,i);
20         }
21     }
22     public void swap(int i,int j){
23         char a = buffer.charAt(i);
24         char b = buffer.charAt(j);
25         buffer.setCharAt(i, b);
26         buffer.setCharAt(j, a);    
27     }
28 }

那么如何解決上面兩點存在的問題呢?這里給推薦一種數據結構,TreeSet。 這個在C++中我不知道有沒有,應該是沒有,但是作為Java程序員,這是比較幸福的地方。

TreeSet這個數據結構本身采用紅黑樹實現,能夠自動將字符串按照字典序排序,同時因為其實現了Set接口,所以又能同時保證所有的結果是一個集合。而學過離散數學的朋友都知道,集合中的元素是不會重復的,所以如果我們采用TreeSet對排列的結果進行存儲,那么就能輕易的達到上述要求。下面是本人實現的代碼:

 1 import java.util.ArrayList;
 2 import java.util.Iterator;
 3 import java.util.List;
 4 import java.util.Set;
 5 import java.util.TreeSet;
 6 public class Solution {
 7    private List<String> list = new ArrayList<>();
 8     private Set<String> set = new TreeSet<>();
 9     private StringBuffer buffer;
10     public ArrayList<String> Permutation(String str) {
11         if(str==null||str.length()==0) return (ArrayList<String>) list;
12         buffer = new StringBuffer(str);
13         PermutationCore(0);
14         Iterator<String> iterator = set.iterator();
15         while(iterator.hasNext()){
16             list.add(iterator.next());
17         }
18         return (ArrayList<String>) list;
19     }
20     public void PermutationCore(int begin) {
21         if(begin==buffer.length()-1){
22             set.add(buffer.toString());
23         }
24         for(int i = begin;i<buffer.length();i++){
25             //if(buffer.charAt(i)==buffer.charAt(begin) && begin!=i) continue;
26             swap(begin,i);
27             PermutationCore(begin+1);
28             swap(begin,i);
29         }
30     }
31     public void swap(int i,int j){
32         char a = buffer.charAt(i);
33         char b = buffer.charAt(j);
34         buffer.setCharAt(i, b);
35         buffer.setCharAt(j, a);    
36     }
37 }

輸入“abc” ,輸出:"abc" "acb" "bac" "bca" "cab" "cba"  ; 輸入“aaa”,輸出"aaa" ,顯然符合要求了。

最后我們來看一看TreeSet的層次結構:

類似的結構還有ArrayList,LinkedList,HashSet,HashMap,TreeMap,PriorityQueue,Stack。另外重要的接口有:List,Set,Map,Queue,Deque,Comparator,Comparable,Itrerator。這些都是在編寫數據結構和算法的時候經常用到的,尤其需要留意。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM