三种全排列方法

方法一:
总体思路:第一种方法是于航算法课程里面的交换字符数组的方法,这种方法的思路是通过交换数组中的两个元素来获取新的排列,交换位坐标k从首位开始,当移动到末位后,则return,而交换位数字一次与他之后的所有元素交换(包含它本身),然后调用递归,并使交换位坐标向后移动一位,然后再回溯。

import java.util.Arrays;

public class N3_1_permutation {
	public static void f(int k,int[] a){
		if(k==a.length-1){
			System.out.println(Arrays.toString(a));
			return ;
		}
		for(int i=k;i<a.length;i++){
			{int tmp=a[k]; a[k]=a[i]; a[i]=tmp;}
			f(k+1,a);
			{int tmp=a[k]; a[k]=a[i]; a[i]=tmp;}
		}
	}
	public static void main(String[] args){
		int [] a = {1,2,3};
		f(0,a);
	}
}

  

方法二:
总体思路:第二种方法的思路是借鉴了leetcode中全排列II的解题思路,它当时是求有重复元素的全排列,因此简化后就是所有元素的全排列,利用列表ArrayList堆栈的性质来实现全排列,再加上一个boolean数组来标记该元素是否被使用,以及一个数组来存储所有用来全排列的元素,for循环遍历所有元素,如果当前元素已经使用,则continue,如果没有使用,则插入列表中,并标记为使用,然后递归,再回溯,删除末位元素,标记改为未使用,当列表的大小与装元素的数组大小相等时return。

import java.util.ArrayList;

public class N3_1_2_permutation {
	
	public static void f(ArrayList<Integer> list,boolean[] used,int[] nums){
		if(list.size()==nums.length){
			System.out.println(list);
			return ;
		}
		for(int i=0;i<nums.length;i++){
			if(used[i]==true) continue;
			used[i]=true;              //利用堆栈的方法实现递归
			list.add(nums[i]);
			f(list,used,nums);
			list.remove(list.size()-1);
			used[i]=false;
		}
	}
	public static void main(String[] args){
		int [] nums ={1,2,3};
		ArrayList<Integer> list = new ArrayList<Integer>();
		f(list,new boolean[nums.length],nums);
	}
}

  

方法三:
总体思路:第三种方法的思路是借鉴了74开头的排列问题的方法,新建一个容量等于排列元素总和的空数组,并设定一个初始值,但是要不等于待排列的任何元素,递归函数中,写一个for循环来遍历充填空数组,当空数组的元素仍然等于初始值时,将n赋值给当前空数组所在位置,然后递归n+1,然后再回溯,重现将该位置元素变为初始值,当待排列元素表示符号超过了所有待排列元素时return。

import java.util.Arrays;

public class N3_1_3_permutation {
	public static void f(int k,int[] a){
		if(k>3){
			System.out.println(Arrays.toString(a));
			return ;
		}
		for(int i=0;i<3;i++){
			if(a[i]==10){
				a[i]=k;
				f(k+1,a);
				a[i]=10;
			}
		}
	}
	public static void main(String[] args){
		int [] a = new int[3];
		for(int i=0;i<3;i++) a[i]=10;  //定义初始值为10
		f(1,a);
	}
}

  

posted @ 2018-12-29 16:07  一个属龙的流浪汉  阅读(874)  评论(0编辑  收藏  举报