博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深度理解递归+递归经典问题实战
阅读量:7226 次
发布时间:2019-06-29

本文共 3218 字,大约阅读时间需要 10 分钟。

内涵

定义

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

递归思想的内涵

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

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

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

递归的三要素

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

递归的应用场景

  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);	}}复制代码

转载于:https://juejin.im/post/5ce6a789e51d45105d63a45d

你可能感兴趣的文章
Android黑科技: 快速找到view所在的xml文件
查看>>
linux分区方案
查看>>
003-Java技术体系
查看>>
超轻量模板引擎
查看>>
JavaScript 复习之 Object对象的相关方法
查看>>
JAVA之流程控制语句
查看>>
Spring Boot(1)
查看>>
Winodws 10 美化与调优
查看>>
apache安装及多域名解析及域名代理
查看>>
什么是自动化运维 ? 自动化运维的设计思路以及实战
查看>>
Python练习实例100例(持续更新中)
查看>>
非父组件通信
查看>>
Electron系列文章-主进程与渲染进程
查看>>
高性能缓存服务器 nuster v1.8.8.2 和 v1.7.11.2 发布
查看>>
教你快速入门ES6
查看>>
Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery
查看>>
宜昌a货翡翠,包头a货翡翠
查看>>
【微信事业群】趣味面试算法题
查看>>
保守的国美再一次进击社交电商,前途未卜?
查看>>
git
查看>>