JVM · Java虚拟机原理 · JVM上语言·框架· 生态系统JavaEE 学习专题java面试集锦

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

2019-12-15  本文已影响0人  Java旺

内涵

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);
    }
}

上一篇 下一篇

猜你喜欢

热点阅读