`
airu
  • 浏览: 270751 次
  • 性别: Icon_minigender_1
  • 来自: 云南
社区版块
存档分类
最新评论

全排列递归思路(java)

 
阅读更多

全排列,full permutation, 经常用于博彩行业。当然我也是一时心血来潮,突然想看看具体如何实现。

这里,我选择递归,因为递归的用法真是多种多样,而且这里正好也反应了一个事实,递归对应着数据结构中的树。

 

根据二叉树的递归遍历,我们认识到了递归的强大,而她的故事也远远不止于此。这里要说的是,二叉树的递归遍历,前中后都简洁的难以置信,但是都有一个共同特点,那就是一个函数里包含两次自身调用。

 

所以,如果一个递归函数中包含了两次自身调用,那么这类问题就是归纳成二分问题。也就是to be or not to be , is the problem。如果一个使用相同手段并且并且每一个点上可分为两种情况的问题,基本都可以转化为递归问题。当然,如果是有三个孩子的树,那么我们可能需要在一个递归函数中调用自身三次。

 

这里的递归,和我们计算阶乘的又有不一样,因为她没有返回,是发散的。也就是从一个节点,发散到N个节点,我们要的结果是叶子节点。

 

计算全排列,我们可以单独拿出每一个元素作为根节点来构成一棵树,所有的可能排列情况就都隐藏在森林中了。现在来看每一颗树,假如4个元素 , A, B, C, D,以A为根是第一颗,表示以A开头的排列。

那么,第二个位置可以选着 B,C, D,如果我们选择了B,那么B下还有 C, D可以选择, 如果我们选了C,那么最后只剩下D,这样,就列出第一种。如图所示:



 

我们可以看到,这里的孩子个数是递减的,直到最后一个元素,就不用选择了,同时也得到一种可能。

要枚举出所有的,那么就遍历这样一颗树。好了,先上代码。

/**
	 * recursive method, used for the tree traversal.
	 * 
	 * @param inStr
	 *            the elements need to be choose
	 * @param pos
	 *            the position of the elements we choose
	 * @param parentData
	 *            the elements have been chosen
	 */
	public void permutation(String inStr, int pos, StringBuffer parentData) {
		if (inStr.length() == 0) {
			return;
		}
		if (inStr.length() == 1) {
			System.out.println("{" + inStr + "}");
			return;
		}
		// here we need a new buffer to avoid to pollute the other nodes.
		StringBuffer buffer = new StringBuffer();
		// copy from the parent node
		buffer.append(parentData.toString());

		// choose the element
		buffer.append(inStr.charAt(pos));

		// get the remnant elements.
		String subStr = kickChar(inStr, pos);

		// got one of the result
		if (subStr.length() == 1) {
			buffer.append(subStr);
			System.out.println(buffer.toString());
			return;
		}

		// here we use loop to choose other children.
		for (int i = 0; i < subStr.length(); i++) {
			permutation(subStr, i, buffer);
		}

	}

	// a simple method to delete the element we choose
	private String kickChar(String src, int pos) {
		StringBuffer srcBuf = new StringBuffer();
		srcBuf.append(src);
		srcBuf.deleteCharAt(pos);
		return srcBuf.toString();
	}

 

真的很简洁。测试一下。

 

public static void main(String args[]) {
		Permutation p = new Permutation();
		StringBuffer buffer = new StringBuffer();
		String input = "ABCD";
		for (int i = 0; i < input.length(); i++) {
			p.permutation(input, i, buffer);
		}
	}

 

注意,这个方法实际上还不能单独使用,必须使用循环把每一个元素都考虑进去。

或许你还有更简洁的方法。当然,从性能上看,递归不是很好。但是我觉得可以考虑从树上去分析。

好了,有空贴上c版本的。

 C版本:

 http://airu.iteye.com/admin/blogs/1936366

  • 大小: 17.3 KB
2
1
分享到:
评论
3 楼 airu 2013-08-27  
说道二叉树,只是大家比较熟悉,通过二叉树,推断出递归调用与树的关系。如果在一个函数内调用自身N 次,那就是N 叉树了。
2 楼 airu 2013-08-27  
xugangqiang 写道
请问图示的abcd例子,如何应用到二叉树分析?
这个算法我写过两个版本,但是没有想到使用二叉树的遍历。
这是一个很好的想法。
但是我没有从楼主的代码里面看到二叉树的遍历。

这不是二叉树,兄弟。
1 楼 xugangqiang 2013-08-26  
请问图示的abcd例子,如何应用到二叉树分析?
这个算法我写过两个版本,但是没有想到使用二叉树的遍历。
这是一个很好的想法。
但是我没有从楼主的代码里面看到二叉树的遍历。

相关推荐

    全排列——递归排序和字典序列

    其基本思路是从集合中依次选取每一个元素作为排列的第一个元素,然后对剩下的元素继续进行全排列,直到所有元素都被排列完成。这种方法利用了递归的特性,不断地分解问题直至达到最简单的基本情况,然后再逐步回溯...

    全排列算法实现(java\c#\c++,各种主流语言版本)

    这些实现遵循了基本的全排列算法思路,即通过递归和回溯来生成所有可能的排列。对于大型数据集,递归可能会导致栈溢出问题,因此有时会考虑非递归的迭代方法,如回溯搜索或者使用堆栈来存储中间状态,以提高效率。在...

    全排列的Hash函数(JAVA)

    在Java中,实现全排列通常会用到递归或者回溯法。Hash函数在这里的作用是将当前的排列状态转换为一个唯一的键(key),然后存储到哈希表中。这样,当生成新的排列时,可以通过Hash函数快速判断这个排列是否已经出现...

    非递归的输出1-N的全排列实例(推荐)

    网易游戏笔试题算法题之一,可以用C++,Java,Python,由于Python代码量较小,于是我选择Python语言。 算法总体思路是从1,2,3……N这个排列开始,一直计算下一个排列,直到输出N,N-1,……1为止 那么如何计算给定排列...

    全排列和棋盘覆盖的java实现代码

    递归的基本思路是,对于n个元素的全排列问题,我们先选择一个元素作为排列的第一个,然后对剩下的n-1个元素进行全排列。这样,每次递归调用都会解决规模更小的问题,直到问题规模缩小到只剩下一个元素或为空,此时...

    字典排序求全排列的算法

    可能包括一个主函数,用于初始化和调用全排列函数,以及一个递归函数,负责生成排列和回溯。 7. **测试与验证**:为了确认算法的正确性,通常会编写一些测试用例,包括边界情况和一些预期的排列。"曲文杰—运行结果...

    FullPermutation(全排列)

    以下是一个简单的全排列实现思路: 1. 初始化一个空的结果列表,用于存储所有可能的全排列。 2. 定义一个递归函数,接受一个当前排列(部分排列)和剩余未使用元素的列表。 3. 在递归函数的基线条件中,如果剩余...

    精心搜集整理:2014年前蓝桥杯Java竞赛历年试题及详尽答案

    这份资源珍稀,不仅囊括了历年Java竞赛的真题,还提供了详细的解题思路与答案,对于即将参赛者及渴望提升Java编程技艺的学习者而言,具有极高的学习价值。 字符序列全排列挑战:此题考察全排列算法,需利用递归逻辑...

    java蓝桥杯历年真题及答案整理(小结)

    在 Java 中,可以使用递归算法来解决全排列问题。具体实现思路是:首先,定义一个递归函数 fullPermutation,该函数接受两个参数:源字符数组和结果字符数组。然后,在递归函数中,对源字符数组进行遍历,对每个字符...

    蓝桥杯java历年真题及答案整理

    - 使用递归方式解决全排列问题。 - 通过两个 `Vector` 类型的变量来存储源字符和当前排列结果。 - 当源字符集为空时,表示完成了一次完整的排列,此时输出结果并计数。 2. **代码解析:** ```java package ...

    Java递归求解数组里“数组合”

    解题思路是使用循环递归算法,首先读取输入的数组元素个数和数组本身,然后通过递归函数`listAll()`生成所有可能的组合。在这个过程中,`listAll()`函数会接收当前处理的子列表和当前组合的前缀字符串作为参数。 在...

    整数数组的全排算法,很经典!!!

    压缩包中的"double"文件可能是实现全排列算法的代码示例,可能是用某种编程语言(如C++、Python、Java等)编写的。通过阅读和理解这段代码,我们可以更深入地掌握全排列的实现细节,并可能从中学习到如何优化内存...

    JAVA练习题(50题)

    - **实现思路**:通过循环或递归的方式计算斐波那契数列中的第n个数字。 #### 练习题2:质数判断 - **知识点**: - 质数的概念:只能被1和自身整除的大于1的自然数。 - 开平方根技巧:减少不必要的检查次数。 - ...

    蓝桥杯大题总结(历届比赛共40多大题) java 版

    1. **递归思路**: - 函数`allPermutation`接受当前索引、原始数组和结果数组作为参数。 - 当原始数组只剩下一个元素时,将这个元素放入结果数组并打印结果。 - 对于剩下的元素,通过递归调用自身实现全排列。 2....

    网上收集的代码

    从给定的文件信息来看,主要涉及的是Java编程语言中关于数字排列组合的实现方法,具体包括了两个示例:一是限制条件下的数字排列问题,二是无限制的全排列组合生成算法。 ### 一、限制条件下的数字排列 在第一个...

    java-lintcode阶梯训练第四章

    5. **递归与回溯**:递归是解决复杂问题的一种常见方法,如斐波那契数列、八皇后问题等。回溯则常用于解决组合优化问题,如全排列、N皇后问题等。 6. **位运算**:在某些优化算法或者处理二进制问题时,位运算是...

    javascript解三阶幻方(九宫格).docx

    本文提供了一个使用 javascript 实现解答九宫格问题的算法,包括递归函数 getPermutation 和非递归的全排列算法。该算法能够找出所有可能的整数填充方案,然后进行过滤,最后输出满足条件的结果。

    华为OD机试C卷- 考古学家(Java & JS & Python).md-私信看全套OD代码及解析

    Java版本的实现采用了递归的方式来进行全排列计算,并使用`TreeSet`来存储石碑碎片内容,确保内容的唯一性和有序性。 ```java import java.util.*; public class JumbledStele { public static void main(String...

    第七届蓝桥杯软件类决赛部分真题(Java语言A组).pdf

    - 使用深度优先搜索(DFS)进行全排列。 - 验证每种排列是否能构成完全平方数。 - 使用 `HashSet` 存储已找到的有效方案,避免重复计数。 **示例代码**(Java): ```java import java.util.Arrays; import java....

    微软Java面试题汇总(最新)

    - **实现思路**:采用分治策略,递归地将链表分为更小的部分,直到每个部分只有一个节点,然后将这些部分合并起来形成有序链表。 - **排序数组**: - **选择方法**:根据数据规模可以选择快速排序、堆排序等。 - ...

Global site tag (gtag.js) - Google Analytics