说说递归

129 阅读2分钟

说说递归

递归模板

image-20220112192003493.png

三定律

def f(x):
    if x == 0:  //结束条件
        return 0
    else:
        return x + f(x -1) //f(x-1)是减少规模和自我调用,减少规模是通过形参自减来实现

最简单的递归

class TestRec{
     int x = 100;
     int sum = 0;
     public int f(x){
          if(x>0){
            return x + f(x-1); //递推,问题减少规模(子问题)
          }else{
            return 0;  // 结束条件
          }
     }
}
​
​
这段递归在运算中没有加任何过滤条件,而只是简单的运算
关于子问题和返回:
   f(x-1)是子问题,并且 return x + f(x-1)子问题返回并不占于何变量做计算。我们当然可也以修改子结构来做个递归过程中过滤
   
  
  def f(x):
    global sum
    if x == 0:
        return 0
    else:
        if x == 3:
            sum = f(x-1) + x
            print 'x is 3'
            print sum
            return x  //这里的x值=x + f(x-1)的结果
            print x
        return x + f(x -1)
​
print(f(100))
=======output=====================
x is 3
6
5047
​
Process finished with exit code 0
   
   sum的值是6,可以看出递归到条件为0反过来1+2+3=6
   因为sum = f(x-1) + x 是在x为3时才运算,所以是3+2+1
   
   此时更上层的是100+99+98...+3压栈,所以返回的结构是100+99+...+4
   
但是x值是反过来的100+99
​
​
​
=================另一个例子=======================
def f(x):
    global sum
    if x == 0:
        return 0
    else:
        if x == 99:
            sum = f(x-1) + x
            print 'x is 99'
            print sum
            print x
            return x
        return x + f(x -1)  //函数的返回
​
print(f(100))
​
x is 99
4950
99
199

递归加过滤条件

def f(x):
    global sum
    if x == 0:
        return 0
    else:
        sum = f(x - 1) + x
        if sum >= 6: // 过滤条件,满足 sum >=6时返回-1
            print sum
            print x
            return -1
        return sum
​
f(100) = -1
为什么sum = f(x - 1) + x ,为什么sum是在运算完已经返回值了理论上值应该是100+99+98...+1 返回sum=5050
​
为什么还可以过滤 sum >=6 这个条件了
​
实际上递归是f(x-1),也是在每减1,都是压一个f(x)函数栈,每个函数栈都有一个sum返回值。
整个压栈过程是x + 99 + 98 递减直到遇到0才终止递减条件,所以相当sum = 6时 ,x= 0 + 1 + 2 + 3
​
​
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
         return height(root) >= 0;
    }
​
    public int height(TreeNode root){
        if(root==null) return 0;  // 结束条件
        int leftH = height(root.left);  
        int rightH = height(root.right);
        if(leftH == -1 || rightH == -1 || Math.abs(leftH-rightH)>1){ // 算出当前节点左右子树的深度差,也就是过滤的逻辑运算
            return -1;
        }else{
            return Math.max(height(root.left),height(root.right))+1; //递归,后序遍历,每次返回当前节点深度
                                                                     //当递归到叶子节点,他的左右儿子实际上是空,所以满足return 0条件,返回来又+1,相当于节点本身的深度,因为是后序遍历
        }
​
        
    }
}