問題:
Given a binary tree, find the leftmost value in the last row of the tree.
Example 1:Input:
image.png
Output:
1Example 2:
Input:
image.png
Output:
7Note: You may assume the tree (i.e., the given root node) is not NULL.
大意:
給出一個(gè)二叉樹,找到樹最下一行的最左邊的節(jié)點(diǎn)值。
例1:輸入:
image.png
輸出:
1例2:
輸入:
image.png
輸出:
7注意:你可以假設(shè)樹(比如,給出根節(jié)點(diǎn))是非空的。
思路:
這道題其實(shí)有可以拆解成兩個(gè)問題:
- 找到二叉樹的最下面一行;
- 在最下面一行找到最左邊的節(jié)點(diǎn)值。
要注意的是,這個(gè)最左邊的節(jié)點(diǎn)值,并不一定是左節(jié)點(diǎn),也可能是最左邊的一個(gè)右子節(jié)點(diǎn)值。
還記得我們在傳送門:LeetCode筆記:102. Binary Tree Level Order Traversal中,是要求將二叉樹一層層地輸出出來。那么通過同樣的方法,我們用BFS廣度優(yōu)先遍歷的方法,利用隊(duì)列,可以確保找到最下一層的所有節(jié)點(diǎn)值,然后只需要用一個(gè)標(biāo)記,來在每次梳理一層的節(jié)點(diǎn)時(shí),將最左邊的一個(gè)節(jié)點(diǎn)值記錄下來,這樣,當(dāng)已經(jīng)確定是最后一層,沒有再下一層后,我們記錄下來的就是最下一層的最左邊的節(jié)點(diǎn)值了。
代碼(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
int result = root.val;
boolean has = false;
while (!queue.isEmpty()) {
int levelNum = queue.size();
for (int i = 0; i < levelNum; i++) {
if (queue.peek().left != null) {
queue.offer(queue.peek().left);
if (!has) {
result = queue.peek().left.val;
has = true;
}
}
if (queue.peek().right != null) {
queue.offer(queue.peek().right);
if (!has) {
result = queue.peek().right.val;
has = true;
}
}
queue.poll();
}
has = false;
}
return result;
}
}
他山之石:
我的這個(gè)方法其實(shí)比較慢,我們看看下面這個(gè)方法:
public class Solution {
public int findBottomLeftValue(TreeNode root) {
return findBottomLeftValue(root, 1, new int[]{0,0});
}
public int findBottomLeftValue(TreeNode root, int depth, int[] res) {
if (res[1]<depth) {res[0]=root.val;res[1]=depth;}
if (root.left!=null) findBottomLeftValue(root.left, depth+1, res);
if (root.right!=null) findBottomLeftValue(root.right, depth+1, res);
return res[0];
}
}
這個(gè)方法的第一個(gè)優(yōu)勢就是代碼確實(shí)比我簡潔多了。。。他的做法其實(shí)跟我第一個(gè)想法差不多,用DFS的方式遞歸來往下找,同時(shí)記錄當(dāng)前找到的節(jié)點(diǎn)所在的深度,他用了一個(gè)int數(shù)組res,數(shù)組第一個(gè)元素記錄節(jié)點(diǎn)值,第二個(gè)元素記錄節(jié)點(diǎn)所在的深度。只有在進(jìn)入更深一層,且這一層還沒有記錄節(jié)點(diǎn)值時(shí),才記錄下找到的第一個(gè)節(jié)點(diǎn)值,其實(shí)也就是最左邊的節(jié)點(diǎn)值,找到后就將深度標(biāo)記為當(dāng)前深度,那么后面找到的所有這個(gè)深度的節(jié)點(diǎn)值都不再記錄,除非又找到了更深的節(jié)點(diǎn)。這樣一直往下,不斷根據(jù)深度來更新找到的節(jié)點(diǎn)值,最后找到的就是最深一層的最左邊的節(jié)點(diǎn)值了。
合集:https://github.com/Cloudox/LeetCode-Record



