回溯法,递归实现。
关于回溯法:
回溯是一种算法思想,可以用递归实现。
递归三部曲:
- 递归函数的功能:dfs(int pos, string s), 表示固定字符串s的pos下标的字符s[pos]
- 递归终止条件:当pos+1 == s.length()的时候,终止,表示对最后一个字符进行固定,也就说明,完成了一次全排列
- 下一次递归:dfs(pos+1, s), 很显然,下一次递归就是对字符串的下一个下标进行固定
import java.util.*;
/**
* 关于去重:利用HashSet存储即可,自动去重;
* 字母表顺序输出:转换为ArrayList后,利用Collections.sort(result);自动排序
*
* */
public class _22字符串的排列 {
public ArrayList<String> Permutation(String str) {
HashSet<String> list = new HashSet<>();
ArrayList<String> result = new ArrayList<>();
if (str == null || str.equals("") || str.length() == 0) return result;
StringBuilder s = new StringBuilder(str);
Permutation_help(list,s,0);
Iterator it = list.iterator();
while(it.hasNext()) {
String item = (String) it.next();
result.add(item);
}
Collections.sort(result);
return result;
}
private void Permutation_help(HashSet<String> list, StringBuilder s, int pos) {
if (pos+1 == s.length()) {
list.add(s.toString());
return;
}
// for循环和swap的含义:对于“ABC”,
// 第一次'A' 与 'A'交换,字符串为"ABC", pos为0, 相当于固定'A'
// 第二次'A' 与 'B'交换,字符串为"BAC", pos为0, 相当于固定'B'
// 第三次'A' 与 'C'交换,字符串为"CBA", pos为0, 相当于固定'C'
for (int i = pos; i < s.length(); i++) {
s = swap(s, pos, i);
Permutation_help(list,s,pos+1);
s = swap(s, i, pos);
// 回溯的原因:比如第二次交换后是"BAC",需要回溯到"ABC"
// 然后进行第三次交换,才能得到"CBA"
}
}
private StringBuilder swap(StringBuilder s, int id1, int id2) {
char temp = s.charAt(id1);
s.setCharAt(id1,s.charAt(id2));
s.setCharAt(id2,temp);
return s;
}
}
京公网安备 11010502036488号