输入一个字符串如abcde按照字典序小到大打印全排列
class Solution { public: vector<string> Permutation(string str) { //可以用递归来做 vector<string> array; if(str.size()==0) return array; Permutation(array, str, 0); sort(array.begin(), array.end()); return array; } void Permutation(vector<string> &array, string str, int begin)//遍历第begin位的所有可能性 { if(begin==str.size()-1) array.push_back(str); for(int i=begin; i<=str.size()-1;i++) { if(i!=begin && str[i]==str[begin])//有重复字符时,跳过 continue; swap(str[i], str[begin]);//当i==begin时,也要遍历其后面的所有字符; //当i!=begin时,先交换,使第begin位取到不同的可能字符,再遍历后面的字符 Permutation(array, str, begin+1);//遍历其后面的所有字符; swap(str[i], str[begin]);//为了防止重复的情况,还需要将begin处的元素重新换回来 /*举例来说“abca”,为什么使用了两次swap函数 交换时是a与b交换,遍历; 交换时是a与c交换,遍历;(使用一次swap时,是b与c交换) 交换时是a与a不交换; */ } } };
下面这种对于重复的如aa 会打印多次。
#include <bits/stdc++.h> using namespace std; int vis[100]; char s[100]; char ans[100]; int n; int dfs(int deep) { if (deep == 5) { printf("%s\n", ans + 1); return 0; } for (int i = 1; i <= n; ++i) { if (!vis[i]) { vis[i] = 1; ans[deep] = s[i - 1]; dfs(deep + 1); vis[i] = 0; } } return 0; } int main() { scanf(" %s", s); n = strlen(s); sort(s, s + strlen(s)); memset(vis, 0, sizeof(vis)); memset(ans, 0, sizeof(ans)); dfs(1); return 0; }
迭代算法:字典生成算法
public ArrayList<String> Permutation(String str) { ArrayList<String> res = new ArrayList<>(); if (str != null && str.length() > 0) { char[] seq = str.toCharArray(); Arrays.sort(seq); //排列 res.add(String.valueOf(seq)); //先输出一个解 int len = seq.length; while (true) { int p = len - 1, q; //从后向前找一个seq[p - 1] < seq[p] while (p >= 1 && seq[p - 1] >= seq[p]) --p; if (p == 0) break; //已经是“最小”的排列,退出 //从p向后找最后一个比seq[p]大的数 q = p; --p; while (q < len && seq[q] > seq[p]) q++; --q; //交换这两个位置上的值 swap(seq, q, p); //将p之后的序列倒序排列 reverse(seq, p + 1); res.add(String.valueOf(seq)); } } return res; } public static void reverse(char[] seq, int start) { int len; if(seq == null || (len = seq.length) <= start) return; for (int i = 0; i < ((len - start) >> 1); i++) { int p = start + i, q = len - 1 - i; if (p != q) swap(seq, p, q); } } public static void swap(char[] cs, int i, int j) { char temp = cs[i]; cs[i] = cs[j]; cs[j] = temp; }
利用栈实现:
public class Solution { public ArrayList<String> Permutation(String str) { TreeSet<String> tree = new TreeSet<>(); Stack<String[]> stack = new Stack<>(); ArrayList<String> results = new ArrayList<>(); stack.push(new String[]{str,""}); do{ String[] popStrs = stack.pop(); String oldStr = popStrs[1]; String statckStr = popStrs[0]; for(int i =statckStr.length()-1;i>=0;i--){ String[] strs = new String[]{statckStr.substring(0,i)+statckStr.substring(i+1),oldStr+statckStr.substring(i,i+1)}; if(strs[0].length()==0){ tree.add(strs[1]); }else{ stack.push(strs); } } }while(!stack.isEmpty()); for(String s : tree) results.add(s); return results; } }