深度理解递归+递归经典问题实战

作者: Java旺 | 来源:发表于2019-12-15 20:37 被阅读0次

内涵

image

定义

在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法。实际上,递归,顾名思义,其包含了两个意思:,这正是递归思想的精华所在

递归思想的内涵

image

递归就是有去(递去)有回(归来)

  • “有去”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决,就像上面例子中的钥匙可以打开后面所有门上的锁一样
  • “有回”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点),一旦到达了这个临界点,就不用再往更小、更远的地方走下去

递归的基本思想就是把规模大的问题转化为规模小的相似的子问题来解决

递归的三要素

  • 明确递归终止条件;
  • 给出递归终止时的处理办法;
  • 提取重复的逻辑,缩小问题规模。

递归的应用场景

  1. 问题的定义是按递归定义的(Fibonacci函数,阶乘,…);
  2. 问题的解法是递归的(有些问题只能使用递归方法来解决,例如,汉诺塔问题,…);
  3. 数据结构是递归的(链表、树等的操作,包括树的遍历,树的深度,…)。

经典递归问题实战

阶乘

public class Factorial {

    public static long f( int n )
    {
        if ( n == 1 ) /* 递归终止条件 */
            return(1); /* 简单情景 */
        return(n * f( n - 1 ) ); /* 相同重复逻辑,缩小问题的规模 */
    }

    public static long f_loop( int n )
    {
        long result = n;
        while ( n > 1 )
        {
            n--;
            result = result * n;
        }
        return(result);
    }
}

斐波纳契数列

public class FibonacciSequence {

    public static int fibonacci( int n )
    {
        if ( n == 1 || n == 2 ) /* 递归终止条件 */
        {
            return(1); /* 简单情景 */
        }
        return(fibonacci( n - 1 ) + fibonacci( n - 2 ) ); /* 相同重复逻辑,缩小问题的规模 */
    }

    public static int optimizeFibonacci( int first, int second, int n )
    {
        if ( n > 0 )
        {
            if ( n == 1 ) /* 递归终止条件 */
            {
                return(first); /* 简单情景 */
            }else if ( n == 2 ) /* 递归终止条件 */
            {
                return(second); /* 简单情景 */
            }else if ( n == 3 ) /* 递归终止条件 */
            {
                return(first + second); /* 简单情景 */
            }
            return(optimizeFibonacci( second, first + second, n - 1 ) ); /* 相同重复逻辑,缩小问题规模 */
        }
        return(-1);
    }

    public static int fibonacci_loop( int n )
    {
        if ( n == 1 || n == 2 )
        {
            return(1);
        }
        int result  = -1;
        int first   = 1; /* 自己维护的"栈",以便状态回溯 */
        int second  = 1; /* 自己维护的"栈",以便状态回溯 */
        for ( int i = 3; i <= n; i++ ) /* 循环 */
        {
            result  = first + second;
            first   = second;
            second  = result;
        }
        return(result);
    }

    public static int fibonacci_array( int n )
    {
        if ( n > 0 )
        {
            int[] arr   = new int[n]; /* 使用临时数组存储斐波纳契数列 */
            arr[0]      = arr[1] = 1;
            for ( int i = 2; i < n; i++ ) /* 为临时数组赋值 */
            {
                arr[i] = arr[i - 1] + arr[i - 2];
            }
            return(arr[n - 1]);
        }
        return(-1);
    }
}

杨辉三角的取值

public static int getValue( int x, int y )
{
    if ( y <= x && y >= 0 )
    {
        if ( y == 0 || x == y ) /* 递归终止条件 */
        {
            return(1);
        }else{
            /* 递归调用,缩小问题的规模 */
            return(getValue( x - 1, y - 1 ) + getValue( x - 1, y ) );
        }
    }
    return(-1);
}
}

回文字符串的判断

/**
 * Title: 回文字符串的判断
 * Description: 回文字符串就是正读倒读都一样的字符串。如"98789", "abccba"都是回文字符
 * 两种解法:
 * 递归判断;
 * 循环判断;
 */
public class PalindromeString {
    /**
     * @description 递归判断一个字符串是否是回文字符串
     * @return
     */
    public static boolean isPalindromeString_recursive( String s )
    {
        int start   = 0;
        int end = s.length() - 1;
        if ( end > start ) {//递归终止条件:两个指针相向移动,当start超过end时,完成判断 
            if ( s.charAt( start ) != s.charAt( end ) ){
                return(false);
            }else{
                /* 递归调用,缩小问题的规模 */
                return(isPalindromeString_recursive( s.substring( start + 1 ).substring( 0, end - 1 ) ) );
            }
        }
        return(true);
    }

    /**
     * @description 循环判断回文字符串
     * @return
     */
    public static boolean isPalindromeString_loop( String s )
    {
        char[] str = s.toCharArray();
        int start   = 0;
        int end = str.length - 1;
        while ( end > start ) //循环终止条件:两个指针相向移动,当start超过end时,完成判断 
        {
            if ( str[end] != str[start] )
            {
                return(false);
            }else{
                end--;
                start++;
            }
        }
        return(true);
    }
}

相关文章

  • 深度理解递归+递归经典问题实战

    内涵 定义 在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法。实际上,递归,顾...

  • 深度理解递归+递归经典问题实战

    内涵 定义 在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法。实际上,递归,顾...

  • 递归详解晋级 php

    递归的理解 递归的方式解决了,深度求解在内的八个经典问题,本文先简洁描述递归树包括阶乘斐波那契数列二分查找汉诺塔杨...

  • 正则问题

    经典的递归DFS 我对递归的理解不够深啊看到括号 应该很轻松的想到是经典的递归问题 然后只有四个符号()x| 分别...

  • LeetCode-N Queens

    N皇后问题。经典回溯问题: 以下是递归及非递归的方法:

  • 数据结构之理解递归

    理解递归 要理解递归, 首先要理解递归 --佚名 递归是一种解决问题的方法, 他从解决问题的各个小部分开始, 知道...

  • 斐波那契数列的Java实现

    基本上算是有两个类型的求解方式:1、递归方式,理解起来最直接,最方便,但是递归算法的空间复杂度大,在递归深度不断增...

  • 学习递归

    1. 递归 1.1 理解递归 ​ 递归是一种解决问题的方法,它从解决问题的各个小部分中开始,直到解决最...

  • 算法笔记:递归,找到最终推荐人

    如何理解递归 递归是一种非常广泛的算法。涉及到的算法有DFS深度优先搜索,前中后序二叉树遍历等 递归,去的过程叫做...

  • CSI讲义8:理解递归

    所有的计算都是递归;要理解递归首先要理解递归。 程序设计思想之一“递归”历来是同学们的理解难点。据说,**要理解递...

网友评论

    本文标题:深度理解递归+递归经典问题实战

    本文链接:https://www.haomeiwen.com/subject/lfylnctx.html