找树左下角的值,最起码要遍历到最后一层,然后找最左边的值,即寻找最深的叶子节点。
本题比较适合迭代法理解,层序遍历
,有两种做法:
🔔法一
🔴定义结果变量和空队列,当根节点不为空时,压入队列。
🔴在队列不为空时,首先判断当前队列的大小,然后,遍历该队列,每次在i=0时,将该节点从队列读取复制给结果先保存,从队列中删除;
🔴再读取其他节点删除,接下来,当该节点还有左节点或者右节点时,将其入队列,重复每次在i=0时,将该节点从队列读取复制给结果先保存。因为每次取i=0其实取得就是左节点的值。
🔔法二
🔴 定义一个结果变量和队列,我们将根节点入队,如果根节点不为空,则读取并从队列中删除头节点,
🔴然后秉持着先进先出的原则,因为最后要得到的是左节点的值,所以我们让左节点一直保证最后一个出队列,即,先将右孩子压入队列,再将左孩子压入队列。这样最后赋值的也是左叶子的值。
🔴因此,在判断节点是否有左右孩子时,应该先将右孩子放入对列,然后再将左孩子放入队列,这样最后一个值就是左孩子的值。
-------------------------------------------分割线
---------------------------------------------
🌈方法一代码如下:
(1)首先,创建一个存放节点的空队列,定义一个结果集。将不为空的根节点放入队列中。
(2)计算当前队列大小,循环遍历每一层的节点,i=0时,即先遍历左节点,读取并删除左节点,当i=0时,将其赋值给res
(3)继续遍历,当该节点的左孩子或右孩子不为空时,将其放入队列,并继续读取刚才队列中正在遍历的节点。每一层的i=0的节点都赋值结果变量res。直到最后一个。
class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int res = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode poll = queue.poll();
if (i == 0) {
res = poll.val;
}
if (poll.left != null) {
queue.offer(poll.left);
}
if (poll.right != null) {
queue.offer(poll.right);
}
}
}
return res;
}
}
🌈方法二代码如下:
class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode p=queue.poll();
if(p.right!=null){
queue.offer(p.right);
}
if(p.left!=null){
queue.offer(p.left);
}
ret=p.val;
}
return ret;
}
}
补充:
1.Queue queue = new
LinkedList<>()
;与Queue queue = new ArrayDeque<TreeNode>()
;定义有什么区别?
LinkedList 和 ArrayDeque 都实现了 Queue 接口,它们之间的主要区别在于底层数据结构不同。
LinkedList 使用双向链表来实现队列,这意味着它支持快速地在队列的两端添加或删除元素,但在随机访问和插入元素时相对较慢。如果应用场景需要在队列的两端频繁地添加或删除元素,则使用 LinkedList 会更好。
而 ArrayDeque 则是使用可扩展的循环数组实现的队列,这意味着它可以在队列两端进行快速地添加或删除元素,并且支持随机访问元素。如果应用场景需要高效的随机访问和在队列的两端进行频繁的添加或删除元素,则使用 ArrayDeque 会更好。、
在本题中,两个实现都是可以使用的,因为题目只涉及到队列的基本操作:入队和出队,所以它们的时间复杂度相同。通常来说,如果应用场景没有明显的性能差异,那么使用更简单的数据结构会更好,所以在本题中,使用 ArrayDeque 更为简洁明了。
2.Queue<TreeNode> queue
与Deque<TreeNode> queue
有什么区别?
Queue 和 Deque 都是 Java 中的接口,其中 Queue 表示一种先进先出(FIFO)的队列,而 Deque 则表示一种双端队列。
Queue 接口只提供了基本的队列操作,如添加元素到队列尾部、从队列头部删除元素、获取队列的头部元素等。而 Deque 接口则提供了更多的操作,如添加元素到队列头部、从队列头部删除元素、从队列尾部添加元素等。
在 Java 中,ArrayDeque 类实现了 Deque 接口,同时也实现了 Queue 接口,因此可以使用 ArrayDeque 作为 Queue 的实现类。而 LinkedList 类则实现了 Queue 接口,但没有实现 Deque 接口。因此,ArrayDeque 可以作为 Queue 和 Deque 的实现类,而 LinkedList 只能作为 Queue 的实现类。
在使用时,如果只需要基本的队列操作,可以使用 Queue 接口及其实现类 LinkedList,如果需要双端队列的操作,则需要使用 Deque 接口及其实现类 ArrayDeque。