1.LeetCode 257.二叉树的所有路径
题目链接:力扣刷题
参考资料:代码随想录
视频讲解:B站视频
给你一个二叉树的根节点 root
,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [1,2,3,null,5] 输出:["1->2->5","1->3"]
思路:1.递归法(回溯)
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
1.递归函数参数以及返回值:根节点,返回的路径,存放节点的数据,返回的是一个string的集合.
2.确定终止条件:终止条件应该是当前节点的左右节点分别为空。
3.确定单层递归逻辑:当root.left 不为空和root.right不为空;
具体JAVA代码如下:
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
if (root == null) {
return res;
}
revers(root, path, res);
return res;
}
public void revers(TreeNode root,List<Integer> path,List<String> res){
// path记录节点的数据
path.add(root.val);
// 如果找到了节点左右2边的数都为空,此时就把他加进去
if(root.left == null && root.right == null){
StringBuilder sb = new StringBuilder();
// 找到path插入的数据,将其他的->也加入进去
for(int i =0; i < path.size()-1;i++){
sb.append(path.get(i)).append("->");
}
// 将最后一个数据加进去
sb.append(path.get(path.size()-1));
res.add(sb.toString());
return;
}
if(root.left != null){
revers(root.left,path,res);
// 获取path的最后一位进行回溯
path.remove(path.size()-1);
}
if(root.right != null){
revers(root.right,path,res);
// 获取path的最后一位进行回溯
path.remove(path.size()-1);
}
}
}
2.层次遍历
借助栈来辅助实现,栈存放2个数据,一个是当前root,一个是走到当前的路径的步骤,2个同时入栈也同时出栈。
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
// 整个的思路就是,运行到了那个节点,那就把从根节点到目前节点的所有东西都存在path里面,最后返回path
List<String> res = new ArrayList<>();
Stack<Object> stack = new Stack<>();
if(root == null){
return res;
}
// 节点和数据一起入栈
stack.push(root);
stack.push(root.val + "");
while (!stack.isEmpty()){
// 节点和数据一起出栈
String path =(String) stack.pop();
TreeNode temp = (TreeNode) stack.pop();
// 如果当前节点的左右孩子都为空,那就把path增加到res里面去,这就是一条路径
if(temp.left == null && temp.right == null){
res.add(path);
}
// 如果左节点不为空,那就把path+“->”+val就存入到栈中。
if(temp.left != null){
stack.push(temp.left);
stack.push(path+"->"+temp.left.val);
}
// 如果右节点不为空,那就把path+“->”+val就存入到栈中。
if(temp.right != null){
stack.push(temp.right);
stack.push(path+"->"+temp.right.val);
}
}
return res;
}
}
2.LeetCode 404.左叶子之和
题目链接:力扣刷题
参考资料:代码随想录
视频讲解:B站视频
给定二叉树的根节点 root
,返回所有左叶子之和。
示例 1:
输入: root = [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
思路一:递归法
递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。
递归三部曲:
- 确定递归函数的参数和返回值
判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int
使用题目中给出的函数就可以了。
2.确定终止条件
如果遍历到空节点,那么左叶子值一定是0
if (root == NULL) return 0;
注意,只有当前遍历的节点是父节点,才能判断其子节点是不是左叶子。 所以如果当前遍历的节点是叶子节点,那其左叶子也必定是0,那么终止条件为:
if (root == NULL) return 0;
if (root->left == NULL && root->right== NULL) return 0; //其实这个也可以不写,如果不写不影响结果,但就会让递归多进行了一层。
3.确定单层递归的逻辑
当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。
java代码如下:
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
//如果当前节点为空,那就返回0
if (root == null) {
return 0;
}
// 如果当前的左右节点为空,只有根节点也返回0;
if (root.left == null && root.right == null) {
return 0;
}
int leftlenght = sumOfLeftLeaves(root.left);
int rightlength = sumOfLeftLeaves(root.right);
int midum =0;
if(root.left != null && root.left.left == null && root.left.right == null){
midum = root.left.val;
}
return leftlenght+rightlength+midum;
}
}
思路二:迭代法
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
// 如果当前节点为空,那就返回0;
if (root == null) {
return 0;
}
// 如果当前节点的左右都为空,那就说明也只有根节点,也返回0
if (root.left == null && root.right == null) {
return 0;
}
int result = 0;
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
TreeNode temp = deque.pollFirst();
if (temp.left != null && temp.left.left == null && temp.left.right == null) {
result += temp.left.val;
}
if (temp.left != null) {
deque.offerLast(temp.left);
}
if (temp.right != null) {
deque.offerLast(temp.right);
}
}
return result;
}
}