字符串的排列求的是字符串的全排列,假设给定的是一个a,b,c的字符串,那么输出的全排列应该是abc,acb等等共6个。

  文章中采用的方法是每次都将当前字符串的第一位依次与后面的某一位交换,来递归完成全排列的过程。每次都将当前字符串分为第一位和后面所有位两部分。

  但是文章中并没有考虑到当输入的字符串有重复的时候,如果仍按照这种方法做,就会导致有冗余的字符串产生,因此需要加一个判断条件,如果两个要交换的字符是一样的,那么就跳过这次交换。

  同时每次开始遍历肯定是从当前第一位开始的,否则遍历是不全的,即会包含自己和自己的交换,具体见如下代码:

  

 1 public class AllPossibleSort{
 2 
 3     public void sort(String [] array,int start){
 4         String temp="";
 5         if(start==array.length-1){
 6             for(int i=0;i<array.length;i++){
 7                 System.out.print(array[i]);
 8             }
 9             System.out.println();
10             return;
11         }
12         for(int i=start;i<array.length;i++){
13             if(i!=start&&array[i]==array[start]){
14                 continue;
15             }
16             //将当前位与后面位交换,一开始是与自身交换
17             temp = array[i];
18             array[i] = array[start];
19             array[start] = temp;
20             //递归向后
21             sort(array,start+1);
22             //相当于回溯,返回交换之前状态
23             temp = array[i];
24             array[i] =array[start];
25             array[start] = temp;
26         }
27     }
28 
29     public static void main(String [] args){
30         String [] array = {"a","b","c","a"};
31         AllPossibleSort aps = new AllPossibleSort();
32         aps.sort(array,0);
33     }
34 }

  以上的代码就能够完成去除冗余的字符串全排列.

  在全排列中还有其他几种相关题目,有一种就是给定一个8个数字的数组,判断这8个数字能不能组成一个立方体,使得相对三面的4个定点之和相等,即a1+a2+a3+a4=a5+a6+a7+a8,a1+a2+a5+a6 =a3+a4+a7+a8,a1+a3+a5+a7=a2+a4+a6+a8。这个的方法就是通过按照上面的方法求出8个数字的全排列,然后看这些排列方案中是否存在可行的方案。

  第二种题目就是著名的8皇后问题了,8皇后问题就是将8皇后放在8*8的棋盘上,使得任意两个皇后不在同一行列和同一对角线上,这个的方法就是典型的回溯法,首先不断深入进行递归找寻,不行就回溯到上一个节点中,再次递归。具体代码如下:

 1 package offer;
 2 
 3 import java.util.ArrayList;
 4 
 5 class Queen{
 6     int x;
 7     int y;
 8     public Queen(int x,int y){
 9         this.x = x;
10         this.y = y;
11     }
12 }
13 
14 public class EightQueens {
15     ArrayList<Queen> list = new ArrayList<Queen>();
16     public void find(int rows,int [][] array){
17         //rows表示当前遍历的是哪一层的情况,因为8个皇后在8*8的棋盘中,那么肯定是每行都有一个
18         if(rows==array.length){
19             //遍历完成,打印可能情况,退出循环
20             for(int i=0;i<list.size();i++){
21                 System.out.println(list.get(i).x+" , "+list.get(i).y);
22             }
23             System.out.println();
24             return;
25         }
26         boolean existed = false;
27         for(int col=0;col<array[rows].length;col++){
28             //在已经找到的节点中遍历当前节点所在的行列和对角线中是否已经有皇后了,如果没有,则放在该节点,如果有了,则右移一位
29             for(int i=0;i<list.size();i++){
30                 if(list.get(i).x==rows || list.get(i).y==col||Math.abs(list.get(i).x-rows)==Math.abs(list.get(i).y-col)){
31                     existed=true;
32                     break;
33                 }
34             }
35             if(!existed){
36                 //如果当前点满足条件,就将当前点加入到list中
37                 Queen q = new Queen(rows,col);
38                 list.add(q);
39                 find(rows+1,array);
40                 list.remove(q);
41             }
42             //这个点若是为true,那么就需要重置existed,否则下个点也是true,那整个一行都不满足条件了
43             existed = false;
44         }
45     }
46     
47     public static void main(String[] args) {
48         // TODO Auto-generated method stub
49         int [][] array = new int [8][8];
50         EightQueens eq = new EightQueens();
51         eq.find(0,array);
52     }
53 
54 }