全排列,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
相关推荐
其基本思路是从集合中依次选取每一个元素作为排列的第一个元素,然后对剩下的元素继续进行全排列,直到所有元素都被排列完成。这种方法利用了递归的特性,不断地分解问题直至达到最简单的基本情况,然后再逐步回溯...
这些实现遵循了基本的全排列算法思路,即通过递归和回溯来生成所有可能的排列。对于大型数据集,递归可能会导致栈溢出问题,因此有时会考虑非递归的迭代方法,如回溯搜索或者使用堆栈来存储中间状态,以提高效率。在...
在Java中,实现全排列通常会用到递归或者回溯法。Hash函数在这里的作用是将当前的排列状态转换为一个唯一的键(key),然后存储到哈希表中。这样,当生成新的排列时,可以通过Hash函数快速判断这个排列是否已经出现...
网易游戏笔试题算法题之一,可以用C++,Java,Python,由于Python代码量较小,于是我选择Python语言。 算法总体思路是从1,2,3……N这个排列开始,一直计算下一个排列,直到输出N,N-1,……1为止 那么如何计算给定排列...
递归的基本思路是,对于n个元素的全排列问题,我们先选择一个元素作为排列的第一个,然后对剩下的n-1个元素进行全排列。这样,每次递归调用都会解决规模更小的问题,直到问题规模缩小到只剩下一个元素或为空,此时...
可能包括一个主函数,用于初始化和调用全排列函数,以及一个递归函数,负责生成排列和回溯。 7. **测试与验证**:为了确认算法的正确性,通常会编写一些测试用例,包括边界情况和一些预期的排列。"曲文杰—运行结果...
以下是一个简单的全排列实现思路: 1. 初始化一个空的结果列表,用于存储所有可能的全排列。 2. 定义一个递归函数,接受一个当前排列(部分排列)和剩余未使用元素的列表。 3. 在递归函数的基线条件中,如果剩余...
这份资源珍稀,不仅囊括了历年Java竞赛的真题,还提供了详细的解题思路与答案,对于即将参赛者及渴望提升Java编程技艺的学习者而言,具有极高的学习价值。 字符序列全排列挑战:此题考察全排列算法,需利用递归逻辑...
在 Java 中,可以使用递归算法来解决全排列问题。具体实现思路是:首先,定义一个递归函数 fullPermutation,该函数接受两个参数:源字符数组和结果字符数组。然后,在递归函数中,对源字符数组进行遍历,对每个字符...
- 使用递归方式解决全排列问题。 - 通过两个 `Vector` 类型的变量来存储源字符和当前排列结果。 - 当源字符集为空时,表示完成了一次完整的排列,此时输出结果并计数。 2. **代码解析:** ```java package ...
解题思路是使用循环递归算法,首先读取输入的数组元素个数和数组本身,然后通过递归函数`listAll()`生成所有可能的组合。在这个过程中,`listAll()`函数会接收当前处理的子列表和当前组合的前缀字符串作为参数。 在...
压缩包中的"double"文件可能是实现全排列算法的代码示例,可能是用某种编程语言(如C++、Python、Java等)编写的。通过阅读和理解这段代码,我们可以更深入地掌握全排列的实现细节,并可能从中学习到如何优化内存...
- **实现思路**:通过循环或递归的方式计算斐波那契数列中的第n个数字。 #### 练习题2:质数判断 - **知识点**: - 质数的概念:只能被1和自身整除的大于1的自然数。 - 开平方根技巧:减少不必要的检查次数。 - ...
1. **递归思路**: - 函数`allPermutation`接受当前索引、原始数组和结果数组作为参数。 - 当原始数组只剩下一个元素时,将这个元素放入结果数组并打印结果。 - 对于剩下的元素,通过递归调用自身实现全排列。 2....
从给定的文件信息来看,主要涉及的是Java编程语言中关于数字排列组合的实现方法,具体包括了两个示例:一是限制条件下的数字排列问题,二是无限制的全排列组合生成算法。 ### 一、限制条件下的数字排列 在第一个...
5. **递归与回溯**:递归是解决复杂问题的一种常见方法,如斐波那契数列、八皇后问题等。回溯则常用于解决组合优化问题,如全排列、N皇后问题等。 6. **位运算**:在某些优化算法或者处理二进制问题时,位运算是...
本文提供了一个使用 javascript 实现解答九宫格问题的算法,包括递归函数 getPermutation 和非递归的全排列算法。该算法能够找出所有可能的整数填充方案,然后进行过滤,最后输出满足条件的结果。
Java版本的实现采用了递归的方式来进行全排列计算,并使用`TreeSet`来存储石碑碎片内容,确保内容的唯一性和有序性。 ```java import java.util.*; public class JumbledStele { public static void main(String...
- 使用深度优先搜索(DFS)进行全排列。 - 验证每种排列是否能构成完全平方数。 - 使用 `HashSet` 存储已找到的有效方案,避免重复计数。 **示例代码**(Java): ```java import java.util.Arrays; import java....
- **实现思路**:采用分治策略,递归地将链表分为更小的部分,直到每个部分只有一个节点,然后将这些部分合并起来形成有序链表。 - **排序数组**: - **选择方法**:根据数据规模可以选择快速排序、堆排序等。 - ...