全排列题解

文章目录

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

解决方案:

递归:

import java.util.ArrayList;
public class Solution {
    ArrayList<String> result = new ArrayList<>(); 
    public void mutation(String str, int index, char[] item) {
        if (index == str.length()){
            result.add(new String(item));
            return;
        }
        char[] sstr = str.toCharArray();
        int[] visit = new int[str.length()];
        for (int i=index;i<sstr.length;i++) {
            if (sstr[i] != sstr[index] || i == index){
                item[index] = sstr[i];
                char tem = sstr[index];
                sstr[index] = sstr[i];
                sstr[i] = tem;
                mutation(new String(sstr),index+1,item);
            }
        }
    } 
    public ArrayList<String> Permutation(String str) {
        if (str.equals("") || str == null)
            return result;
         char[] item = new char[str.length()];
         mutation(str,0,item);
         return result;
    }
}

字典序算法:

全排列,一个很好的思路:

  1. 对字符串或数字组合进行进行排序,递增
  2. 从末尾开始向前遍历每个元素,直到当前元素小于前面的元素,记当前的位置为 i
  3. 以 i-1 位置处的元素的值为准,记为stan,从i开始向后遍历,直到最后一个大于stan的元素,记其位置为 j
  4. 交换位置为i-1和j处的元素
  5. 从位置i开始到集合末尾范围内的元素,反向排列
  6. 步骤2-5便得出了集合的下一个排列,添加到结果集合中
  7. 重复步骤2-6,直到集合满足从末尾向前遍历,直到第一个元素,一直都满足递增关系

思路的原理是:假设是一个字符串集合,n个元素,从第0个到第n-1个元素都是递增,那么这肯定是第一个排列;相反如果从第n-1个到第0个元素都是递增,那么这肯定是最后一个排列了

import java.util.ArrayList;
import java.util.Arrays;
public class Solution {  
   public ArrayList<String> Permutation(String str) {
        ArrayList<String> result = new ArrayList<>();
        if (str.length() == 0 || str == null) {
            return result;
        }
        //排序
        char[] array = str.toCharArray();
        Arrays.sort(array);
        result.add(new String(array));

        while (true) {

            int i = array.length - 1;
            while (i>0 && array[i]<=array[i-1]) {
                i--;
            }
            if (i==0)
                break;
            int j = i;
            while (j<array.length && array[j]>array[i-1]) {
                j++;
            }
            if (j==array.length)
                j = array.length-1;
            else
                j = j-1;

            swap(array,i-1,j);
            reverse(array,i);
            result.add(new String(array));
        }
        return result;
    }
    public void reverse (char[] chars, int i) {
        int j = i;
        int k = chars.length - 1;
        while (j < k) {
            swap(chars, j, k);
            j++;
            k--;
        }
    }
    public void swap (char[] chars, int i, int j) {
        char tem = chars[i];
        chars[i] = chars[j];
        chars[j] = tem;
    }
}

参考文章:

[字典序全排列算法研究](http://www.cnblogs.com/pmars/archive/2013/12/04/3458289.html)

点赞