- 全排列模板-数组 2013年 第四届 蓝桥杯【带分数】
- 全排列模板-字符数组 2014年 第五届 蓝桥杯【扑克排序】
- 全排列模板-无重复元素 2016年 第七届 蓝桥杯【凑算式】
1.全排列 交换回溯法
无字典排序
public static void main(String[] args) {
int a[]= {1,2,3};
f(a,0);
}
private static void f(int[] a, int k) {
if (k==a.length) {
for (int x:a) {
System.out.print(x);
}
System.out.println();
}else {
for (int i = k; i < a.length; i++) {
int t=a[i];
a[i]=a[k];
a[k]=t;
f(a, k+1);
t=a[i];
a[i]=a[k];
a[k]=t;
}
}
}
2.全排列 前缀法
有字典排序
public static void main(String[] args) {
String string = "123";
f("", string.toCharArray());
}
private static void f(String k, char[] arr) {
if (k.length() == arr.length) {
System.out.println(k);
}
for (int i = 0; i < arr.length; i++) {
char ch = arr[i];
// 理解点:这个字符可用:在k中出现的次数<在字符集出现的次数
if (counts(k, ch) < counts(arr, ch)) {
f(k + ch, arr);
}
}
}
static int counts(char[] arr, char ch) {
int sum = 0;
for (char c : arr) {
if (c == ch) {
sum++;
}
}
return sum;
}
static int counts(String s, char ch) {
int sum = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ch)
sum++;
}
return sum;
}
3.啊哈算法里的搜索第一节 抓取法
选数字放入三个箱子 这种感觉
static int a[] = new int[10] ;
static int book[] = new int[10];
static int n = 3;//n等于几就是1-几的全排列
static void dfs(int step) {//取数法
//思路 有三个位置 取数字往里面放 第一次放1 标记1没了 只有2 3以此推
if (step == n+1) {//三个箱子为例 第四个箱子没数字了 只有3个结束
for (int i = 1; i <= n; i++) {
System.out.print(a[i]);
}
System.out.println();
return;
}
for (int i = 1; i <=n; i++) {
if (book[i] == 0) { //该数字还可以拿
book[i] = 1;//标记 就是已经放入了箱子 拿不了
a[step] = i;
dfs(step + 1);
book[i] = 0;//其实就是标记回溯
}
}
return;
}
public static void main(String[] args) {
dfs(1);
/*123
132
213
231
312
321
* */
}
4.组合全排列
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
dfs(0,list);
}
private static void dfs(int k, List<Integer> list) {
if (k==3) {//k=几就是几位数
for (int x:list) {
System.out.print(x);
}
System.out.println();
}
for (int i = 1; i <=3; i++) {//4选3 4可以是n
if (list.contains(i)) {
continue;
}
list.add(i);
dfs(k+1, list);
list.remove(list.size()-1);
}
}
5 3中的抓取法去重
public class dfs {
static int a[] = new int[10] ;
static boolean book[] = new boolean[10];
static int n = 3;//n等于几就是1-几的全排列
static int ss[]= {1,2,2}; //122的全排列
static void dfs(int step) {//取数法
//思路 有三个位置 取数字往里面放 第一次放1 标记1没了 只有2 3以此推
if (step == n+1) {
for (int i = 1; i <= n; i++) {
System.out.print(a[i]);
}
System.out.println();
return;
}
for (int i = 0; i <3; i++) {
//去重 *******
if (i>0&&ss[i]==ss[i-1]&&!book[i-1]) {
continue;
}
if (!book[i]) {
book[i] = true;
a[step] = ss[i];
dfs(step + 1);
book[i] = false;//其实就是标记回溯
}
}
return;
}
public static void main(String[] args) {
dfs(1); /*122
212
221/
/*123
132
213
231
312
321
* */
}
}