剑指Offer——全排列递归思路
剑指Offer——全排列递归思路
前言
全排列,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,这样,就列出第一种。如图所示:
我们可以看到,这里的孩子个数是递减的,直到最后一个元素,就不用选择了,同时也得到一种可能。
要枚举出所有的,那么就遍历这样一颗树。好了,先上代码。
package cn.edu.ujn.nk;
public class FullPermutation {
/**
* 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[]) {
FullPermutation p = new FullPermutation();
StringBuffer buffer = new StringBuffer();
String input = "ABCD";
for (int i = 0; i < input.length(); i++) {
p.permutation(input, i, buffer);
}
}
}
美文美图
剑指Offer——全排列递归思路的更多相关文章
- 【剑指offer】部分思路整理
题目 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去 ...
- 剑指offer 8.递归和循环 跳台阶
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 解题思路一: a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是 ...
- 【剑指offer】递归循环两种方式反转链表
转载请注明出处:http://blog.csdn.net/ns_code/article/details/25737023 本文分别用非递归和递归两种方式实现了链表的反转,在九度OJ上AC. 题目描写 ...
- 剑指offer 9.递归和循环 变态跳台阶
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 这道题还是编程题? 数学渣渣看到心拔凉拔凉的, 要用到数学归纳法来 ...
- 剑指offer 10.递归和循环 矩形覆盖
题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 当n=0时 ,target=0: 当n=1时 ,ta ...
- 剑指offer 7. 递归和循环 斐波那契数列
题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 简简单单 废话不多说,直接上代码: public class Sol ...
- 《剑指offer》内容总结
(1)剑指Offer——Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常 ...
- 【剑指offer】和为定值的连续正数序列
.可是他并不满足于此,他在想到底有多少种连续的正数序列的和为100(至少包含两个数).没多久,他就得到还有一组连续正数和为100的序列:18,19,20,21,22.如今把问题交给你,你能不能也非常快 ...
- 【剑指offer】复制的复杂链条
转载请注明出处:http://blog.csdn.net/ns_code/article/details/26154691 题目描写叙述: 输入一个复杂链表(每一个节点中有节点值,以及两个指针,一个指 ...
随机推荐
- UVA 12161 Ironman Race in Treeland
题目大意: 每一条边都有两个权值,val和路径长度d,要保证在val<=m 的条件下,求最长的d. 解题报告: 一开始想错了,后来发现还不如直接暴力点分,思想很套路.. 平时我们统计时,都会用合 ...
- bzoj2683简单题 cdq分治
2683: 简单题 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1803 Solved: 731[Submit][Status][Discuss] ...
- Java并发编程:JMM(Java内存模型)和volatile
1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部 ...
- 作为开发也要了解的 mysql 优化思路
作为开发人员,数据库知识掌握的可能不是很深入,但是一些基本的技能还是要有时间学习一下的.作为一个数据库菜鸟,厚着脸皮来总结一下 mysql 的基本的不能再基本的优化方法. 为了更好的说明,我假想出来了 ...
- 如何使用GitHub
进行版本控制时,我们可以直接通过网页来进行版本控制,也可以下载git客户端.值得注意的是,git的客户端有很多种,具体的可以参考:https://git-scm.com/downloads/guis/ ...
- Python中dict的功能介绍
Dict的功能介绍 1. 字典的两种函数(方法) 1. 字典的内置函数 包含关系 格式:x.__contains__(key)等同于key in x 例如:dic = {'ab':23,'cd':34 ...
- xadmin库的下载安装及奇葩报错的解决方法
今天主要讲xadmin库的下载和安装的.......各种问题....... 先注明:我使用的是python3.6,Django2.0,所以xadmin也应该是2.0版本会比较适配. 所以这里先给个xa ...
- Spring中<context:annotation-config/>
最近在研究Spring中<context:annotation-config/>配置的作用,现记录如下: <context:annotation-config/>的作用是向Sp ...
- Windows转Linux总结(附带常用Linux命令-LinuxMint)
这是我在Linux系统下写的第一篇博客,花了一周的时间从Windows系统转到Linux并且可以完成日常操作,能在Linux系统下完成开发,运用各种开发工具,写各种语言小程序和JavaEE. 经过这一 ...
- 聪明的搜索算法’ A*算法
A*算法 是一种启发式的搜索算法. 了解BFS.DFS或者Dijkstra算法的人应该知道.这些算法都是一种向四周盲目式搜索的方法. 启发式搜索: 启发式搜索就是在状态空间中的搜索 ...