1. 程式人生 > 其它 >劍指offer-字串的排列

劍指offer-字串的排列

描述

輸入一個字串,打印出該字串中字元的所有排列,你可以以任意順序返回這個字串陣列。例如輸入字串abc,則按字典序打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。

輸入描述:

輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字母。 求解思路:
  1. 首先遇到重複問題,首先想到通過集合,以嘗試解決字元重複的問題,簡化問題。
  2. 然後就是比較簡單的遞迴了:
    • 確定遞迴函式功能(有點類似DP中確定狀態,不過一個是結果,一個是動作):返回第第i個字元字元到最後一個字元的全排列。
    • 確定出口和邏輯處理(可先畫遞迴樹結構尋找規律)。
程式碼:
 1
#include<iostream> 2 using namespace std; 3 #include<queue> 4 #include<vector> 5 #include<string> 6 #include<set> 7 8 class Solution { 9 public: 10 // 通過集合解決重複的問題,簡化問題 11 // 然後就是一個很簡單的遞迴了。 12 vector<string> Permutation(string str) { 13 // 將集合轉換為vector
14 vector<string> st; 15 if(str.empty()){ 16 return st; 17 } 18 set<string> se=permaute(str); 19 set<string>::iterator ite=se.begin(); 20 21 for(;ite!=se.end();++ite){ 22 st.push_back(*ite); 23 }
24 return st; 25 } 26 27 // 每次遞迴,弄一個集合,然後返回上層遞迴時,將集合和當前字元組合 28 set<string> permaute(string remain){ 29 set<string> curSet; 30 int len=remain.size(); 31 if(len==1){ 32 curSet.insert(remain); 33 return curSet; 34 } 35 for(int i=0;i<len;++i){ 36 // 更新下一層的remain 37 string br=remain; 38 string::iterator ite=br.begin(); 39 std::advance(ite,i); // 向後移動i個位置 40 br.erase(ite); 41 // int a=1; 42 set<string> belowSet=permaute(br); 43 // 組合下一層的集合 44 set<string>::iterator site=belowSet.begin(); 45 while(!belowSet.empty() && site!=belowSet.end()){ 46 curSet.insert(remain[i]+*site); 47 ++site; 48 } 49 } 50 return curSet; 51 } 52 }; 53 54 int main() { 55 Solution* sol = new Solution(); 56 string remain="ab"; 57 vector<string> vs=sol->Permutation(remain); 58 vector<string>::iterator ite=vs.begin(); 59 for(;ite!=vs.end();++ite){ 60 string el=*ite; 61 for(int i=0;i<el.size();++i){ 62 cout<<el[i]; 63 } 64 cout<<endl; 65 } 66 return 0; 67 }
心之所願,永不相忘