題目:
輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。
輸入描述:
輸入一個字符串,長度不超過9(可能有字符重復),字符只包括大小寫字母。
分析:
可以采用遞歸和非遞歸兩種方法實現。
遞歸方法使用交換的的思路,我們可以將字符串看成兩部分,第一個字符和后面的字串,將第一個字符和后面的每一元素互換,這樣就會產生新的排列,然后再遞歸執行后面的字串,具體流程如圖:
出自:https://blog.csdn.net/zxzxzx0119/article/details/81452269
第二種方法可以先取一個元素到結果集,然后遍歷字串剩余的元素將每一個元素插入到結果集中字符串的每一個位置,刪掉取出的結果,再講新結果存進結果集用{a,b,c}舉例。
結果集中是{a}
取結果集字符串{a},並在結果集中刪掉{a},將剩余元素b插入串{a}的每一個位置得到{b,a},{a,b}。
取{b,a},結果集還剩{a,b}
將c插入{b,a}得到{c,b,a},{b,c,a},{b,a,c},將三個結果添加進結果集,此時{a,b},{c,b,a},{b,c,a},{b,a,c}
再取出{a,b}將c插入得,{c,a,b},{a,c,b},{a,b,c},添加進結果集,此時{c,b,a},{b,c,a},{b,a,c},{c,a,b},{a,c,b},{a,b,c}
小技巧就是每次從結果集的后面取出元素,在前面插入新的結果。
不過這道題要求是有重復元素的,可以使用set來去重,不過牛客網的判題很迷,順序不同也會判錯。可以排個序再輸出。
程序:
C++
class Solution { public: vector<string> Permutation(string str) { if(str.size() == 0) return res; helper(str, 0); for(auto i:tempRes) res.push_back(i); return res; } void helper(string str, int index){ if(index == str.size()-1) //res.push_back(str); tempRes.insert(str); for(int i = index; i < str.size(); ++i){ swap(str[index], str[i]); helper(str, index+1); } } vector<string> res; set<string> tempRes; };
class Solution { public: vector<string> Permutation(string str) { if(str.size() == 0) return res; res.push_back(str.substr(0, 1)); strSet.insert(str.substr(0, 1)); for(int i = 1; i < str.size(); ++i){ int m = res.size(); for(int j = 0; j < m; ++j){ string tempStr = res.back(); res.pop_back(); for(int k = 0; k <= tempStr.size(); ++k){ string ttempStr = tempStr; ttempStr.insert(k, str.substr(i,1)); set<string>::iterator iter; if((iter = strSet.find(ttempStr)) == strSet.end()){ res.insert(res.begin(), ttempStr); strSet.insert(ttempStr); } } } } sort(res.begin(), res.end()); return res; } private: set<string> strSet; vector<string> res; };
Java
import java.util.ArrayList; import java.util.Collections; //import java.util.HashSet; public class Solution { public ArrayList<String> Permutation(String str) { if(str.length() == 0) return res; StringBuilder s = new StringBuilder(str); Helper(s, 0); Collections.sort(res); return res; } public void Helper(StringBuilder s, int index){ if(index == s.length()-1) res.add(s.toString()); for(int i = index; i < s.length(); ++i){ if(s.charAt(index) != s.charAt(i) || index == i){ Swap(s, index, i); Helper(s, index+1); Swap(s, index, i); } } } public static void Swap(StringBuilder s, int i, int j) { char temp = s.charAt(i); s.setCharAt(i, s.charAt(j)); s.setCharAt(j, temp); } private ArrayList<String> res = new ArrayList<>(); //private HashSet<String> set = new HashSet<>(); }