剑指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——全排列递归思路的更多相关文章

  1. 【剑指offer】部分思路整理

    题目 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去 ...

  2. 剑指offer 8.递归和循环 跳台阶

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果).   解题思路一: a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是 ...

  3. 【剑指offer】递归循环两种方式反转链表

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/25737023 本文分别用非递归和递归两种方式实现了链表的反转,在九度OJ上AC. 题目描写 ...

  4. 剑指offer 9.递归和循环 变态跳台阶

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法.   这道题还是编程题?   数学渣渣看到心拔凉拔凉的,   要用到数学归纳法来 ...

  5. 剑指offer 10.递归和循环 矩形覆盖

    题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?   当n=0时 ,target=0:   当n=1时 ,ta ...

  6. 剑指offer 7. 递归和循环 斐波那契数列

    题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 简简单单 废话不多说,直接上代码: public class Sol ...

  7. 《剑指offer》内容总结

    (1)剑指Offer——Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常 ...

  8. 【剑指offer】和为定值的连续正数序列

    .可是他并不满足于此,他在想到底有多少种连续的正数序列的和为100(至少包含两个数).没多久,他就得到还有一组连续正数和为100的序列:18,19,20,21,22.如今把问题交给你,你能不能也非常快 ...

  9. 【剑指offer】复制的复杂链条

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/26154691 题目描写叙述: 输入一个复杂链表(每一个节点中有节点值,以及两个指针,一个指 ...

随机推荐

  1. 【 lca倍增模板】

    题目描述 对于 n(<100000)个点 n-1 条掉权值的边,有 m 个询问,每条询问求两个结点之间的路径上边权的最小值 输入 第一行 n,表示结点个数,接下来 n-1 行,每行 a b w ...

  2. [HNOI2015]实验比较

    Description 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 N 张图片,编号为 1 到 N.实验分若干轮进行,在每轮实验中,小 D会被要求观看某两张随机选 ...

  3. hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)

    了校赛,还有什么途径可以申请加入ACM校队?  覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  4. poj 1845 (逆元 + 约数和)

    题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 思路: A可以表示为A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数 那么A的 ...

  5. [usaco6.1.1Postal Vans]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 给你一个4*n的棋盘,问从(1,1)出发恰好经过所有格子一次的走法数量.(n<=1000) 插头dp,用f[i][j][k]表示转移到第 ...

  6. [Spoj]Counting Divisors (cube)

    来自FallDream的博客,未经允许,请勿转载,谢谢. 设d(x)表示x的约数个数,求$\sum_{i=1}^{n}d(i^{3})$ There are 5 Input files. - Inpu ...

  7. 安装ipython,使用scrapy shell来验证xpath选择的结果 | How to install iPython and how does it work with Scrapy Shell

    1. scrapy shell 是scrapy包的一个很好的交互性工具,目前我使用它主要用于验证xpath选择的结果.安装好了scrapy之后,就能够直接在cmd上操作scrapy shell了. 具 ...

  8. 数据结构 单链表&顺序表

    顺序表: 一般使用数组(C语言中的数组采用顺序存储方式.即连续地址存储)来描述. 优点:在于随机访问元素, 缺点:插入和和删除的时候,需要移动大量的元素. 链表: 优点:插入或删除元素时很方便,使用灵 ...

  9. servlet的web-xml配置详解

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...

  10. jQuery 安装

    网页中添加 jQuery 可以通过多种方法在网页中添加 jQuery. 您可以使用以下方法: 从 jquery.com 下载 jQuery 库 从 CDN 中载入 jQuery, 如从 Google ...