引言
二叉树本身就是使用递归而生成的,所以在解决相关问题的时候,首先是使用递归来做,
但是因为算法的时间和空间的问题,所以尽量将递归转换为迭代来做。
递归解题思路
递归,就是在运行的过程中调用自己。
构成递归需具备的条件:
1. 子问题须与原始问题为同样的事,且更为简单;
2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。
要点:
1. 先确定自己要做的事情的最小单元,并以将其写出来;
这是因为 子问题和原始问题是同样的事情, 所以确定子事情,那么原始问题也就确定了
2. 找出子问题的终止条件;
这是因为递归最终都是需要结束的,也就是返回一个结果,所以你要确定最小单元需要返回什么结果(return what)
以及他的结束条件是什么。
3. 找出原始问题如何转化 为子问题的条件方式:
这里面一般就是 进入return A + B 的这种形式
https://blog.csdn.net/qq_41635352/article/details/90452366
别人的步骤:
-
找整个递归的终止条件:递归应该在什么时候结束?
-
找返回值:应该给上一级返回什么信息?
-
本级递归应该做什么:在这一级递归中,应该完成什么任务?
发现自己上面的步骤缺少了一点: 就是想想应该给上一级返回什么信息
所以上述步骤总结为: 找出最小问题(我们只需要关注这一级的解决过程), 最小问题如何停止,大问题转小问题;(编程的思想是自底层向上层编写, 实现是从自上向下执行)
递归案例:
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
实现代码:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public boolean hasPathSum(TreeNode root, int sum) { int count = 0; return preOder(root, count,sum); } private Boolean preOder(TreeNode root, int sum,int expect){ if(root == null){ return false; } sum += root.val; // 1、最小单元,做的事情 if(root.left == null && root.right == null){ // 2、终止条件 return sum == expect; } return preOder(root.left, sum, expect) || preOder(root.right, sum , expect) ; ///3、 将大问题转化为子问题 } }
非递归思路