题目:数字1,2,3,4全排列。

全排列

思路:使用递归策略将待排数列逐一缩小。例如1,2,3,4。先把1固定,递归求2,3,4的全排列;又把2固定,递归求3,4全排列......直到只剩一个数,输出这个排列。图解如下:

    private static void permutation(int[] array, int index) {
        if (index == array.length - 1)
            System.out.println(Arrays.toString(array));

        //从固定的数,与后面每一位交换
        for (int i = index; i < array.length; i++) {
            swap(array, i, index);
            permutation(array, index + 1);//确定第index位的数值
            swap(array, i, index);
        }
    }

	private static void swap(int[] array, int i, int index) {
		int temp=array[i];
		array[i]=array[index];
		array[index]=temp;
	}

带重复值的全排列

例如:1,2,3,2

当进行到index=0时,固定{1}+P(2,3,2),接下来求子串(2,3,2)的全排列,但其中有两个2,无论哪个与此时的1交换,后面的子串都相同,会重复。故需要跳过保留其中一种就可以了,查询是否重复的区间为当前进行到的位置index和准备交换的位置i,在i之前若有重复的,则说明index位置元素不需要再与i位置交换计算了。代码如下:

	private static void permutation(int[] array, int index) {
		if (index == array.length - 1)
			System.out.println(Arrays.toString(array));

		// 用当前位值,与后面每一位交换
		for (int i = index; i < array.length; i++) {
			 if(check(array,index,i)){
	            	swap(array, i, index);
	            	permutation(array, index + 1);//确定第index位的数值
	            	swap(array, i, index);
	          }
		}
	}

	private static boolean check(int[] array, int index, int i) {
		if (i > index) {//兼容index=i的情况
			for (int j = index; j < i; j++) {
				if (array[j] == array[i])
					return false;
			}
		}
		return true;
	}

	private static void swap(int[] array, int i, int index) {
		int temp = array[i];
		array[i] = array[index];
		array[index] = temp;
	}