三种全排列方法
Posted h-meng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三种全排列方法相关的知识,希望对你有一定的参考价值。
方法一:
总体思路:第一种方法是于航算法课程里面的交换字符数组的方法,这种方法的思路是通过交换数组中的两个元素来获取新的排列,交换位坐标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); } }
以上是关于三种全排列方法的主要内容,如果未能解决你的问题,请参考以下文章