赞
踩
目录
2.4 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回 1+7+2+9,它的和是19
相信大家都听过一个故事:
从前有坐山,山上有座庙,庙里有个老和尚给小和尚将故事,讲的就是:
"从前有座山,山上有座庙,庙里有个老和尚给小和尚讲故事,讲的就是:
"从前有座山,山上有座庙..."
"从前有座山……"
"
上面的故事有个特征:自身中又包含了自己,因为有些时候,我们遇到的问题直接并不好解决,但是发现将原问题拆分成其子问题之后,子问题与原问题有相同的解法,等子问题解决之后,原问题就迎刃而解了,这也正是递归的思想
一个方法在执行过程中调用自身, 就称为 "递归"
递归相当于数学上的 "数学归纳法", 有一个起始条件, 然后有一个递推公式.
例如, 我们求 N!
起始条件: N = 1 的时候, N! 为 1. 这个起始条件相当于递归的结束条件.
递归公式: 求 N! , 直接不好求, 可以把问题转换成 N! => N * (N-1)!
递归的必要条件:
1. 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同
2. 递归出口
递归的程序的执行过程不太容易理解, 要想理解清楚递归, 必须先理解清楚 "方法的执行过程", 尤其是 "方法执行结束 之后, 回到调用位置继续往下执行"
- public class Test {
- public static void main(String[] args) {
- int n = 3;
- int ret = fac(n);
- System.out.println(ret);//6
- }
-
- public static int fac(int n){
- if(n == 1){
- return 1;
- }
- return n * fac(n-1);//fac调用函数自身
- }
- }
递归的详细操作:(用三个图详解)
- public class Test {
- public static void main(String[] args) {
- int n = 1234;
- num(n);
- }
- public static void num(int n){
- if(n >= 9){
- num(n/10);
- }
- System.out.println(n % 10);
- }
-
- }
- public class Test {
- public static void main(String[] args) {
- int sum = 10;
- int ret = sum(10);
- System.out.println(ret);
- }
- public static int sum(int n){
- if(n == 1){
- return n;
- }
- else{
- return n + sum(n-1);
- }
- }
- }
- public class Test {
- public static void main(String[] args) {
- int n = 1729;
- int ret = sum(n);
- System.out.println(ret);
- }
- public static int sum(int num){
- if(num < 10){
- return num;
- }
- return num % 10 + sum(num / 10);
- }
-
- }
- public class Test {
- public static void main(String[] args) {
- System.out.println(fib(5));
- }
- public static int fib(int n){
- if(n == 1){
- return 0;
- }
- if(n == 2){
- return 1;
- }
- return fib(n-1) + fib(n-2);
- }
- }
那么既然递归如此方便,我们就要盲选递归么,当然不是,就拿斐波那契数列来说
看以下代码:
- public class Test {
- public static int count = 0;
- public static void main(String[] args) {
- System.out.println(fib(40));
- System.out.println(count);
- }
- public static int fib(int n){
- if(n == 1){
- return 0;
- }
- if(n == 2){
- return 1;
- }
- if(n == 3){
- count++;
-
- }
- return fib(n-1) + fib(n-2);
- }
- }
如上图运算结果所示当求fib(40)时,count出现了次,出现了冗余运算,此时的执行效率其实并不如循环方法。
那么让我们看看循环方法:
- public class Test {
- public static void main(String[] args) {
- int n = 40;
- int ret = fib(n);
- System.out.println(ret);
- }
- public static int fib(int n){
- int l1 = 0;
- int l2 = 1;
- int l3 = 0;
- for(int i = 3; i <= n; i++){
- l3 = l1 + l2;
- l1 = l2;
- l2 = l3;
- }
- return l3;
- }
- }
所以并不能盲选递归,当数据大的时候,其实循环效率会更高
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。