組合排列、全排列 面試算法(5)

問題:

給定字符串 abcdefg ,請給出其:

①全排列;  (★)

②組合排列。(★☆)j_0028.gif


基本概念

排列

    一般地,從n個不同元素中取出mmn)個元素,按照一定的順序排成一列,叫做從n個元素中取出m個元素的一個排列(Sequence,Arrangement, Permutation)

全排列

    當m=n時所有的排列情況叫全排列。

        全排列數f(n)=n!(定義0!=1)


算法

基本算法

(A)字典序

(B)遞增進位制數法

(C)遞減進位制數法

(D)鄰位對換法

生成樹

遞歸


實現一般多爲遞歸,暫且給出遞歸的方法吧,以後有方法會補充的。

組合排列算法實現1

一種很迅速就想起來的,比較水的方法,就是窮舉了,如下:

package com.java.interview.algorithm;

public class Full_Permutation {
	private static int count = 0;

	public static void main(String[] args) {
		String string = "abcdefg";
		// String string = "abc";
		int length = string.length();
		int re_count = 0;
		int permutation = permutation(string, length, re_count);
		// System.out.println("遞歸了 " + permutation + " 次!");
	}

	public static int permutation(String string, int length, int re_count) {
		if (length == re_count) {
			return count;
		}
		StringBuilder str_copy = new StringBuilder(string);
		String str_copy2 = str_copy.substring(1) + str_copy.charAt(0);
		count++;
		for (int i = 0; i < length; i++) {
			System.out.println(str_copy.substring(0, i + 1));
		}
		return permutation(str_copy2, length, count);
		// String str_copy2 = str_copy.substring(1) + str_copy.charAt(0);
		// return permutation(str_copy2, length, count);
	}
}

組合排列及全排列算法實現2

package com.java.interview.algorithm;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Full_Permutation_Final {
	private static int total;
	private static int total_all;

	public static void main(String[] args) {
		// String string = "abcdefg";//總共有 13699 中組合!
		// String string = "abcd";//64
		// string 不能有重複的字母
		String string = "abc";//
		int length = string.length();
		permutation(string, length);
		permutation_All(string, length);
	}

	public static void permutation_All(String string, int length) {
		total_all = 0;
		String[] strings = new String[length];
		for (int i = 0; i < strings.length; i++) {
			strings[i] = string.charAt(i) + "";
		}
		sort_num(Arrays.asList(strings), new ArrayList<String>(), length);
		System.out.println("全排列總共有 " + total_all + " 中組合!");
	}

	public static void permutation(String string, int length) {
		total = 0;
		String[] strings = new String[length];
		for (int i = 0; i < strings.length; i++) {
			strings[i] = string.charAt(i) + "";
		}
		for (int j = 0; j < length; j++) {
			sort_num(Arrays.asList(strings), new ArrayList<String>(), j + 1);
		}
		System.out.println("總共有 " + total + " 中組合排列!");
	}

	/**
	 * 遞歸算法:將數據分爲兩部分,遞歸將數據從左側移右側實現全排列
	 *
	 * @param datas
	 * @param target
	 */
	private static void sort_num(List<String> datas, List<String> target,
			int num) {
		if (target.size() == num) {
			for (Object obj : target)
				System.out.print(obj);
			System.out.println();
			total++;
			total_all++;
			// 遞歸條件下每一層的return只能返回到上一層,而不能跳出整個遞歸函數
			// 即通過return恢復datas與target
			return;
		}
		for (int i = 0; i < datas.size(); i++) {
			List<String> newDatas = new ArrayList<String>(datas);
			List<String> newTarget = new ArrayList<String>(target);
			newTarget.add(newDatas.get(i));
			newDatas.remove(i);
			sort_num(newDatas, newTarget, num);
		}
	}
}


全排列算法實現3(參考)

public class FullSort {
	// 將NUM設置爲待排列數組的長度即實現全排列
	private static int NUM = 2;

	/**
	 * 遞歸算法:將數據分爲兩部分,遞歸將數據從左側移右側實現全排列
	 *
	 * @param datas
	 * @param target
	 */
	private static void sort(List datas, List target) {
		if (target.size() == NUM) {
			for (Object obj : target)
				System.out.print(obj);
			System.out.println();
			return;
		}
		for (int i = 0; i < datas.size(); i++) {
			List newDatas = new ArrayList(datas);
			List newTarget = new ArrayList(target);
			newTarget.add(newDatas.get(i));
			newDatas.remove(i);
			sort(newDatas, newTarget);
		}
	}

	public static void main(String[] args) {
		String[] datas = new String[] { "a", "b", "c", "d" };
		sort(Arrays.asList(datas), new ArrayList());
	}
}

另外一種百科上的遞歸算法:(遞歸-恢復-遞歸-恢復)

package com.java.interview.algorithm;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * Title:全排列算法
 * </p>
 *
 * <p>
 * Copyright: http://blog.csdn.net/sunyujia/
 * </p>
 *
 * @author 孫鈺佳
 * @main [email protected]
 * @date 2009-04-25 23:57:23 PM
 */
public class Full_Permutation_Final2 {
	public static char[] text = { 'a', 'b', 'c', 'd', 'e' };

	public static void main(String[] args) {
		permutation(text, 0, text.length);
		System.exit(0);
	}

	/**
	 * 全排列輸出
	 *
	 * @parama[]要輸出的字符數組
	 * @paramm輸出字符數組的起始位置
	 * @paramn輸出字符數組的長度
	 */
	public static void permutation(char a[], int m, int n) {
		int i;
		char t;
		if (m < n - 1) {
			permutation(a, m + 1, n);
			for (i = m + 1; i < n; i++) {
				t = a[m];
				a[m] = a[i];
				a[i] = t;
				permutation(a, m + 1, n);
				t = a[m];
				a[m] = a[i];
				a[i] = t;
			}
		} else {
			printResult(a);
		}
	}

	/**
	 * 輸出指定字符數組
	 *
	 * @param將要輸出的字符數組
	 */
	public static void printResult(char[] text) {
		for (int i = 0; i < text.length; i++) {
			System.out.print(text[i]);
		}
		System.out.println();
	}
}

暫時到這裏了,以後有機會再補充!

以上算法全部經過驗證通過,如有問題,請留言!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章