全排列问题:如,求解字符串“ABC”中所有字符的全排列( 不包含重复 ) ,该问题的解为:ABC ACB BAC BCA CAB CBA。
//分治回溯算法解决全排列问题 不得重复
public class FullPermutation {
public static void main(String[] args) {
String str = "ABC";
char[] arr = str.toCharArray();
HashSet<String> set = new HashSet<>(); //将结果存放在HashSet中来避免出现重复情况
permutation(set, arr, 0, arr.length - 1); //对字符串进行全排列
System.out.println(set);
}
//对字符串进行全排列
private static void permutation(HashSet<String> set, char[] arr, int from, int to) {
//from为字符串区间的开头 to为字符串区间的结尾 当from==to时 表示已经生成了全排列中的一种情况
if(from == to){
set.add(String.valueOf(arr));
}else {
/*
当from!=to时 遍历字符串 从from开始到to为止
第一次从字符串0位置开始 首先0位置的元素自己跟自己交换
向后递归 更新from的值 从from开始到to为止遍历字符串 首先1位置的元素自己跟自己交换
再向后递归 更新from的值 发现from==to 则表示已经有一种情况出现 将该情况添加到集合中
回溯到上一层循环 字符串2位置的元素与from位置的元素交换
再向后递归 更新from的值 发现from==to 则表示又有一种情况出现 将该情况添加到集合中
(该层已经没有其他情况了)
回溯到上一层循环 字符串1位置的元素与from位置的元素交换
向后递归 更新from的值 从from开始到to为止遍历字符串 首先1位置的元素自己跟自己交换
再向后递归 更新from的值 发现from==to 则表示已经有一种情况出现 将该情况添加到集合中
回溯到上一层循环 字符串2位置的元素与from位置的元素交换
再向后递归 更新from的值 发现from==to 则表示又有一种情况出现 将该情况添加到集合中
循环此步骤即可
注意:每次交换完位置 递归到下一层 都要将上一层的元素位置交换回去 否则 回溯时元素就错位了
*/
for (int i = from; i <= to; i++){
swap(arr, i, from);
permutation(set, arr, from + 1, to);
swap(arr, i, from);
}
}
}
//交换两个数据的位置
private static void swap(char[] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}