字符串的全排列 Java实现

前言:在笔试和面试的过程中,多次遇到字符串的全排列问题,这里实现两个典型的例子,用来加深一下理解,大家可以参考参考。

题目1描述:输入为{'a','b','c'},则输出其全排列为:abc, acb, bac, bca, cba, cab。若输入的是一个长度为n的字符数组,则全排列的组合为n!个。

题目2描述:输入为{'a','b',‘b’,'c'},则输出其不重复的全排列,结果如下:

[a, b, b, c]

[a, b, c, b]

[a, c, b, b]

[b, b, a, c]

[b, b, c, a]

[b, a, b, c]

[b, a, c, b]

[b, c, a, b]

[b, c, b, a]

[c, b, b, a]

[c, b, a, b]

[c, a, b, b]

题目1

代码如下:

public class FullPermutation {
	
	/**
	 * @author Norte
	 * 
	 * Date:2018-07-26
	 * 
	 * 功能:字符串的全排列
	 * 
	 * 基本思想:每次从字符数组中选取一个元素(从第一个开始到最后一个结束),作为结果的第一元素,剩下的元素做全排列,
	 * 很明显这是一个递归的过程,递归结束标志为所选取的元素为字符数组的最后一个元素
	 * */
	
	public static void finishFullPermutation(char[] array) {
		permutation(array, 0, array.length);
	}
	
	public static void permutation(char[] array, int start, int end) {
		if(end < 0) { //字符数组中没有元素直接返回
			return;
		}
		if(start == end) { 
			System.out.println(array);
		}else {
			for(int i = start; i < end; i++) {
				swap(array, i, start); //更换前缀
				permutation(array, start + 1, end); //递归将剩余元素全排列
				swap(array, start, i);  //将前缀换回,以便进行上一个前缀的全排列
			}
		}
	}
	
	public static void swap(char[] array, int i, int j) { //用来交换前缀
		char tmp = array[i];
		array[i] = array[j];
		array[j] = tmp; 
	}
	
	public static void main(String[] args) {
		char[] array = {'a','b','c'};
		finishFullPermutation(array);
	}

}

运行结果如下:

abc
acb
bac
bca
cba
cab

题目二

代码如下:

public class RealFullPermutation {
	
	/**
	 * @author Norte
	 * 
	 * Date:2018-07-26
	 * 
	 * 功能:字符数组中的字符有重复元素,实现不重复的全排列组合
	 * 
	 * 基本思想:在实现全排列的基础上,将结果进行筛选,将全排列的结果放在一个list中,放入之前通过contains()方法,
	 * 进行判断,如果list中已经包含该组合,则该组合不放入list中。
	 * 
	 * */
	
	public static List<String> list = new ArrayList<>();
	
	public static void finishFullPermutation(char[] array) {
		if(list != null) {   //调用该方法前判断存放组合的list是否为空,也顺便解决了多次调用要清空list的问题
			list.removeAll(list);
		}
		permutation(array, 0, array.length);
	}
	
	public static void permutation(char[] array, int start, int end) {   
		if(end < 0) {
			return;
		}
		if(start == end) {
			String node = Arrays.toString(array); //将组合转换为字符串方便判断
			if(!list.contains(node)) { //判断该组合在list中是否已经存在
				list.add(node);
				System.out.println(node); //打印list中的组合
			} 
		}else {
			for(int i = start; i < end; i++) {
				swap(array, i, start);
				permutation(array, start + 1, end);
				swap(array, start, i);
			}
		}
	}
	
	public static void swap(char[] array, int i, int j) { //用来交换前缀
		char tmp = array[i];
		array[i] = array[j];
		array[j] = tmp; 
	}
	
	public static void main(String[] args) {
		char[] array = {'a','b','b','c'};
		finishFullPermutation(array);
	}
}

运行结果如下:

[a, b, b, c]
[a, b, c, b]
[a, c, b, b]
[b, a, b, c]
[b, a, c, b]
[b, b, a, c]
[b, b, c, a]
[b, c, b, a]
[b, c, a, b]
[c, b, b, a]
[c, b, a, b]
[c, a, b, b]

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值