遞歸全排列問題(兩種方法 Java實現)

遞歸全排列問題(Java實現)

問題描述

  • 生成 {1,2,…,n} 的所有 n! 個排列

算法

1. 固定位置放元素


  • 算法思想

    • 生成元素{2,3,…,n}的所有排列,並且將元素1放到每個排列的開頭
    • 生成元素{1,3,…,n}的所有排列,並將數字2放到每個排列的開頭
    • 重複這個過程,直到元素{2,3,…,n-1}的所有排列都產生,並將元素n放到每個排列的開頭
  • Java源代碼

/*
 * 若塵
 */
package perm;

import java.util.Arrays;

/**
 * 全排列問題(遞歸)
 * @author ruochen
 * @version 1.0
 */
public class GeneratiingPerm {

	public static int count = 0;
	
	public static void main(String[] args) {
		char[] arr = {'a', 'b', 'c'};
		int start = 0;
		int end = arr.length - 1;
		perm(arr, start, end);
		System.out.println("共有 " + count + " 種排列方式");
	}
	
	/**
	 * 實現全排列
	 * @param arr 待求全排列數組
	 * @param start 開始位置
	 * @param end 結束位置
	 */
	public static void perm(char[] arr, int start, int end) {
		if (start == end) {
			count++;
			System.out.println(Arrays.toString(arr));
		} else {
			for (int i = start; i <= end; i++) {
				swap(arr, start, i);
				perm(arr, start + 1, end);
				// 爲了排列不會丟失,我們這裏在交換回來,使得每次都是以一個固定序列開始
				swap(arr, start, i);
			}
		}
	}
	
	/**
	 * 交換兩個數組元素
	 * @param arr 數組
	 * @param i 第一個元素下標
	 * @param j 第二個元素下標
	 */
	public static void swap(char[] arr, int i, int j) {
		char temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
}


  • 時間複雜度
    T(n)={θ(1)n=1nT(n1)+nn>1T(n) = \begin{cases} θ(1) & n = 1 \\ nT(n - 1) + n & n > 1 \\ \end{cases}

2. 固定元素找位置

  • 算法思想
    1. 首先,我們把 n 放在的位置P[1]上,並且用子數組P[2…n]來產生前n-1個數的排列
    2. 接着,我們將 n 放在P[2]上,並且用子數組P[1]和P[3…n]來產生前n-1個數的排列
    3. 然後,我們將 n 放在P[3]上,並且用子數組P[1…2]和P[4…n]來產生前n-1個數的排列
    4. 重複上述過程直到我們將 n 放在P[n]上,並且用子數組P[1…n]來產生前n-1個數的排列
  • Java源代碼
public static void perm2(char[] arr, int start, int end) {
	if (end == 0) {
		System.out.println(Arrays.toString(arr));
	} else {
		for (int i = start; i <= end; i++) {
			if (arr[i] == 0) {
				arr[i] = (char) end;
				perm2(arr, start, end - 1);
				arr[i] = 0;
			}
		}
	}
}
  • 時間複雜度
    T(n)={θ(1)n=1nT(n1)+nn>1T(n) = \begin{cases} θ(1) & n = 1 \\ nT(n - 1) + n & n > 1 \\ \end{cases}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章