mio4 Java Web & Web Security

字符串的排列

2018-09-01
mio4

阅读:


字符串的排列

题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

分析

  • 只需要得到所有的字符串,然后对集合进行排序即可
  • 对于这种问题,可以先从abc的例子入手,从特殊解到一般解
    • 第一步:没有固定的字符,将a和a、b、c分别交换得到abc、bac、cba
    • 第二步:对于每一种情况,将第一个字符固定,对剩下的部分进行交换(比如对于abc,将a固定,将b和b、c进行交换得到abc、acb)
  • 将问题拆分为小的部分,很明显是一种递归,递归结束的条件是遍历到了字符串的末尾
  • 边界条件
    • 空字符串
import java.util.ArrayList;
import java.util.Collections;

public class Solution {
	public ArrayList<String> Permutation(String str) {
		ArrayList<String> result = new ArrayList<String>();
		if(str == null) //边界条件
			return result;

		char[] cs = str.toCharArray();
		PermutationHelper(cs,0,result);
		Collections.sort(result);
		return result;
	}
	public void PermutationHelper(char[] cs, int i, ArrayList<String> result){ //字符集合,固定元素位置,结果集
		if(i == cs.length-1){
			if(!result.contains(new String(cs))){
				result.add(new String(cs)); //String()构造方法传参为char[]数组,生成字符串
				return; //返回到上一层
			}
		} else{
			for(int j=i; j < cs.length; j++){
				Swap(cs,i,j);
				PermutationHelper(cs,i+1,result); //这里为什么i成为了i+1?表示当前层的交换进行成功,第i个元素已经固定
				Swap(cs,i,j); //复原数组到上一步
			}
		}
	}

	public void Swap(char[] cs, int i, int j){
		char tmp = cs[i];
		cs[i] = cs[j];
		cs[j] = tmp;
	}
}
  • 这道题理解了很久,很有回溯法的精髓
  • 首先是变量的含义
    • i表示从下标0开始到i(不包含i)的字符是已经固定的
    • j用于从i到数组末尾的字符的交换
    • 因为数组只有一个,每次从栈中退回需要还原之前的状态
    • 对于最后的结果,使用Collections.sort()方法进行字典序排序

上一篇 扑克牌顺子

下一篇 序列化二叉树

Comments

Content