`
yeaya
  • 浏览: 4191 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

非递归算法解台阶问题,倒退算法

阅读更多
题目:一个人登台阶,一次能登一级、二级或者三级台阶,假设有n级的台阶,请编写一个java的程序将各种的走法打印出来。

问题帖见:http://www.iteye.com/topic/786239
shkailiao给出了简单的递归算法。

night_stalker也给出了优化后的递归算法。night_stalker的算法效率高了很多,具体见http://night-stalker.iteye.com/blog/789096

正如大家知道的,递归算法是一种很有效的思想方式,可以解决很多的问题。但性能往往不是最优的。

对于这个问题,本人想出来一个算法,不需要递归,直接循环计算,简称“倒退算法”或者“进位算法”。性能比递归算法要高1到2个数量级,当然这是去除IO输出的,毕竟IO是这里最大的瓶颈。
当n=20,一共计算121415个走法
递归算法耗时:312ms
本算法耗时:47ms
当n=25,一共计算2555757个走法
递归算法耗时:7110ms
本算法耗时:329ms

首先确定一种初始走法,以后每一种走法都是在之前的走法的基础上做细小的变化而产生。

举个例子解释一下,当n=6:
首先输出第一种走法:
1,1,1,1,1,1
将最后一步减1,最后第二步加1,输出
1,1,1,1,2
将最后一步减1,最后第二步加1,输出
1,1,1,2,1
将最后一步减1,最后第二步加1,输出
1,1,1,3
将最后一步减1,最后第二步加1,由于3-1=2需要将2分解为2个1,输出
1,1,2,1,1
将最后一步减1,最后第二步加1,输出
1,1,2,2
将最后一步减1,最后第二步加1,输出
1,1,3,1
将最后一步减1,最后第二步加1,由于3+1=4需要进位并分解为2个1,输出
1,2,1,1,1
重复以上步骤,直到第一位为4,说明运算完成。

    void printOut(String s) {
    //  System.out.print(s);
    }

    void printOut(char[] c, int len) {
    //  System.out.print(s);
    }

    static char ccc[] = {'0', '1', '2', '3'};

    private void printOne(int steps[], int len) {

        if (len > 0) {
            printOut(ccc[steps[0]]);
        }
        for (int i = 1; i < len; i++) {
            printOut(',');
            printOut(ccc[steps[i]]);
        }
        printOut("\r\n");
    }

    public void yaoyuan(int n) {

        if (n <= 0) {
                return;
        }
        // 存放所有的走法
        int steps[] = new int[n];
        // 初始化为每步走1个台阶
        for (int i = 0; i < n; i++) {
                steps[i] = 1;
        }
        // 输出第一种走法
        printOne(steps, n);

        int pre = 0;
        int last = n - 1;
        while (last > 0) {
            pre = last - 1;
            switch (steps[last]) {
            case 1: {
                steps[pre]++;
                steps[last]--;
                last--;
                break;
            }
            case 2: {
                steps[pre]++;
                steps[last] = 1;
                break;
            }
            case 3: {
                steps[pre]++;
                steps[last] = 1;
                last++;
                steps[last] = 1;
                break;
            }
            }

            // 是否需要进位
              while (pre > 0 && steps[pre] == 4) {
                steps[pre] = 1;
                pre--;
                steps[pre]++;

                last++;
                steps[last] = 1;
                last++;
                steps[last] = 1;
            }
            // 是否已经结束
              if (pre == 0 && steps[0] == 4) {
                break;
            }
            // 输出一种走法
              printOne(steps, last + 1);
        }
    }


分享到:
评论

相关推荐

    Hanoi塔问题的一种非递归算法

    Hanoi塔问题作为计算机科学领域内经典的递归问题之一,因其简洁性和挑战性而广受关注。通常,Hanoi塔问题的解决方案多采用递归算法,尽管其逻辑清晰、易于理解,但在实际应用中却面临时间和空间效率的问题。尤其是在...

    汉诺塔问题的非递归算法

    在`main()`函数中,用户输入圆盘数量,然后调用这些函数来执行汉诺塔问题的非递归解。 通过非递归算法解决汉诺塔问题,我们能够理解如何用有限的步骤完成看似复杂的问题,这在理解和设计计算机算法中具有重要意义。...

    5!递归算法和非递归算法

    非递归算法不直接调用自身,而是通过循环等其他方式来解决问题。这种方式通常更加直观易懂,也更容易理解和实现。非递归算法在处理迭代过程时非常有效,尤其是在需要显式控制迭代流程的情况下。 ### 示例分析 为了...

    中序遍历二叉树非递归算法

    非递归算法通过使用栈来模拟递归调用过程,从而避免了递归带来的潜在问题。算法的关键在于正确地管理栈,确保按照中序遍历的顺序访问所有节点。 #### 3. 算法步骤详解 在给定的代码片段中,我们可以看到一个典型的...

    二叉树先序、中序、后序三种遍历的非递归算法

    二叉树三种遍历非递归算法 二叉树是一种常用的数据结构,它广泛应用于计算机科学和软件工程中。二叉树的遍历是指对二叉树中的每个结点进行访问的过程。常见的二叉树遍历方法有三种:先序遍历、中序遍历和后序遍历。...

    数据结构DFS深度优先遍历非递归算法实现

    数据结构DFS深度优先遍历非递归算法实现,是自己编写的,可靠。

    先序遍历非递归算法(C语言)

    根据给定的信息,本文将详细解释三种二叉树非递归遍历算法的实现方法:先序遍历、中序遍历以及后序遍历,并重点介绍先序遍历的非递归算法在C语言中的具体实现。 ### 先序遍历非递归算法(C语言) #### 1. 算法概述...

    数据结构 二叉树三种遍历的非递归算法(背诵版).doc

    在计算机科学中,数据结构是组织、存储和处理数据的方式,而二叉树是一种重要的数据结构,它由节点构成,每个节点...通过背诵和理解这些非递归算法,可以提高解决相关问题的能力,并有助于在面试或项目开发中灵活运用。

    递归算法与非递归转化

    递归算法是把问题转化为规模缩小了的同类问题的子问题,然后递归调用函数(或过程)来表示问题的解。递归的效率一般不高,但是递归比较符合人类的思维方式。一般而言非递归算法更有效;但很多时候递归算法容易实现,...

    汉诺塔递归与非递归两种算法的代码与结果对比

    "非递归解决汉诺塔,每一步都有确切解.doc"文件很可能提供了非递归算法的详细步骤和解释,每一步都确保了盘子的合法移动,确保最终能将所有盘子从A移动到C。 **结果对比** "no differences"的结果表明,无论使用...

    二叉树先序遍历、中序遍历和后序遍历非递归算法 C++源码

    用C++写的二叉树先序遍历、中序遍历和后序遍历非递归算法

    二叉树遍历的非递归算法分析与实现

    ### 二叉树遍历的非递归算法分析与实现 #### 一、引言 在数据结构领域中,二叉树作为一种基本的数据组织形式,其应用极为广泛。对于二叉树的操作,其中最重要的就是遍历操作。遍历是指按照特定顺序访问二叉树的...

    递归算法与非递归算法的转换文.pdf

    相比之下,非递归算法通常使用循环或栈来解决问题,避免了递归带来的额外开销。非递归算法占用的栈空间较少,效率较高。例如,上述代码展示了一个非递归算法 `_q`,它使用一个栈 `s` 来模拟递归过程,逐个处理问题的...

    二叉树后序遍历的非递归算法。

    该算法可以解决二叉树的后序遍历问题,不需要使用递归函数,可以减少函数调用次数,提高算法的效率。 知识点: 1. 二叉树的定义:二叉树是一种树形结构,每个结点最多有两个孩子结点,即左孩子和右孩子。 2. ...

    遍历二叉树的非递归算法

    ### 遍历二叉树的非递归算法 #### 概述 在计算机科学领域,二叉树是一种常见的数据结构,在很多应用中都扮演着重要角色。对于二叉树的遍历,通常有三种主要的方式:前序遍历、中序遍历以及后序遍历。这些遍历方式...

    二叉树先序、中序、后序遍历非递归算法

    ### 二叉树先序、中序、后序遍历非递归算法 #### 前言 在计算机科学中,二叉树是一种常见的数据结构,它被广泛应用于各种算法和程序设计中。二叉树的遍历是理解并操作二叉树的基础,通常有三种主要的遍历方式:...

    Ackermann函数的非递归算法

    function of ackermann

    二叉树前序、中序、后序三种遍历的非递归算法(C语言)

    通常,这些遍历算法是以递归方式实现的,但递归虽然简洁,却可能带来栈溢出的问题,尤其是在处理大规模数据时。因此,了解和掌握二叉树的非递归遍历算法至关重要。 ### 前序遍历非递归算法 前序遍历的顺序是:根...

    C++ 二叉树的先序遍历、中序遍历和后序遍历非递归算法

    用C++写的,包括二叉树的构建,二叉树的先序遍历、中序遍历和后序遍历非递归算法。

    折半查找的递归与非递归算法

    以上是对折半查找算法及其递归和非递归实现的详细解析。在实际编程中,理解并运用这些概念对于提高搜索效率,特别是在处理大量数据时,具有重要意义。在 `biSearch.java` 文件中,我们可以看到具体的代码实现,这将...

Global site tag (gtag.js) - Google Analytics