前言
经过数模比赛的四天忙碌后博主继续开始LeetCode学习了,给大家分享学习心路的同时也是在不断勉励自己每天把自己的学的东西去进行一个产出记录,不足的地方欢迎大家批评指正, 一起加油吧朋友们!💪💪💪
左叶子之和
LeetCode题目链接
给定二叉树的根节点root要求返回所有左叶子之和
首先要明确左叶子的概念。🤔🤔🤔由下图可以看出,判断一个节点是不是左叶子是要根据其父结点来判断的,即节点的左节点不为空,然后呢节点的左节点的左节点为空,节点的左节点的右节点也为空,则说明找到了一个左叶子,这也是我们递归单层处理逻辑的核心一步✨✨✨。

递归三要素如下:
1
| private int sumOfLeftNodes(TreeNode root){}
|
1 2
| if(root == null){return 0;} if(root.left == null && root.right == null){return 0;}
|
1 2 3 4 5
| if(root.left != null && root.left.left == null && root.left.right == null){ return root.left.val + sumOfLeftNodes(root.right); } return sumOfLeftNodes(root.right) + sumOfLeftNodes(root.right);
|
完整代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public int sumOfLeftLeaves(TreeNode root) { if(root == null){return 0;} return sumOfLeftNodes(root); }
private int sumOfLeftNodes(TreeNode root){ if(root == null){return 0;} if(root.left == null && root.right == null){return 0;}
if(root.left != null && root.left.left == null && root.left.right == null){ return root.left.val + sumOfLeftNodes(root.right); } return sumOfLeftNodes(root.left) + sumOfLeftNodes(root.right); } }
|
接着来处理迭代的情况,我们用栈来进行数据保存,遇到左叶子进行弹栈求和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public int sumOfLeftLeaves(TreeNode root) { if(root == null){return 0;} Stack<TreeNode> stack = new Stack<>(); stack.push(root); int result = 0; while(!stack.isEmpty()){ TreeNode cur = stack.pop(); if(cur.left != null && cur.left.left == null && cur.left.right == null){ result += cur.left.val;
} if(cur.right != null){stack.push(cur.right);} if(cur.left != null){stack.push(cur.left);} } return result; } }
|
找树左小角的值
LeetCode题目链接
给定一个二叉树的根节点root,请找出该二叉树的 最底层 最左边 节点的值。
我们先梳理思路,首先肯定是层序遍历会比较简单,而递归的话就是递归遍历到最后一层对吧,找最左边节点的话我们就保持最左优先处理即可,那怎么判断到最后一层了呢?计算深度,深度最大的节点一定是最后一行的节点。🤔🤔🤔

我们来一起确定下递归三要素
1 2 3 4 5 6 7
|
int Depth = -1; int val = 0; private void findLeftNodeVal(TreeNode root, int depth){}
|
1 2 3 4 5 6 7
| if(root == null){return;} if(root.left == null && root.right == null){ if(Depth < depth){ val = root.val; Depth = depth; } }
|
1 2
| if(root.left != null){findLeftNodeVal(root.left, depth + 1);} if(root.right != null){findLeftNodeVal(root.right, depth + 1);}
|
完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution {
private int Depth = -1; private int val = 0;
public int findBottomLeftValue(TreeNode root) { val = root.val; findLeftNodeVal(root, 1); return val; }
private void findLeftNodeVal(TreeNode root, int depth){ if(root == null){return;} if(root.left == null && root.right == null){ if(Depth < depth){ val = root.val; Depth = depth; } } if(root.left != null){findLeftNodeVal(root.left, depth + 1);} if(root.right != null){findLeftNodeVal(root.right, depth + 1);} } }
|
接着来处理迭代的情况,使用层序遍历,每行只用判断第一个节点的值即可,用队列来存储遍历的节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public int findBottomLeftValue(TreeNode root) { int result = 0; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while(!queue.isEmpty()){ int size = queue.size(); for(int i = 0; i < size; i++){ TreeNode cur = queue.poll(); if(i == 0){ result = cur.val; } if(cur.left != null){queue.offer(cur.left);} if(cur.right != null){queue.offer(cur.right);} } } return result; } }
|
下图为双端队列的两端出入队的方法,因为比较容易混淆🤔🤔🤔

除了出入队,还有两端元素的查看操作,这里的话peek和get有一些差别,peek方法 查看元素但不抛出异常,如果队列为空则返回null,而get方法 查看元素,但如果队列为空会抛出异常,这点也容易混淆🤔🤔🤔

总结
今天就到这里啦,保安在赶人了,明天继续加油!!✊✊✊