Given a binary tree, find the leftmost value in the last row of the tree.

Example 1:

Input:

    2
/ \
1 3 Output:
1

Example 2:

Input:

        1
/ \
2 3
/ / \
4 5 6
/
7 Output:
7

Note: You may assume the tree (i.e., the given root node) is not NULL.

這道題讓我們求二叉樹的最左下樹結點的值,也就是最後一行左數第一個值,那麼我首先想的是用先序遍歷來做,我們維護一個最大深度和該深度的結點值,由於先序遍歷遍歷的順序是根-左-右,所以每一行最左邊的結點肯定最先遍歷到,那麼由於是新一行,那麼當前深度肯定比之前的最大深度大,所以我們可以更新最大深度為當前深度,結點值res為當前結點值,這樣在遍歷到該行其他結點時就不會更新結果res了,參見程式碼如下:

解法一:

class Solution {
public:
int findBottomLeftValue(TreeNode* root) {int max_depth = , res = root->val;
helper(root, , max_depth, res);
return res;
}
void helper(TreeNode* node, int depth, int& max_depth, int& res) {
if (!node) return;
if (depth > max_depth) {
max_depth = depth;
res = node->val;
}
helper(node->left, depth + , max_depth, res);
helper(node->right, depth + , max_depth, res);
}
};

其實這道題用層序遍歷更直接一些,因為層序遍歷時遍歷完當前行所有結點之後才去下一行,那麼我們再遍歷每行第一個結點時更新結果res即可,根本不用維護最大深度了,參見程式碼如下:

解法二:

class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int res = ;
queue<TreeNode*> q{{root}};
while (!q.empty()) {
int n = q.size();
for (int i = ; i < n; ++i) {
TreeNode *t = q.front(); q.pop();
if (i == ) res = t->val;
if (t->left) q.push(t->left);
if (t->right) q.push(t->right);
}
}
return res;
}
};

我們還可以使用個小trick,使得其更加的簡潔,由於一般的層序是從左往右的,那麼如果我們反過來,每次從右往左遍歷,這樣就不用檢測每一層的起始位置了,最後一個處理的結點一定是最後一層的最左結點,我們直接返回其結點值即可,參見程式碼如下:

解法三:

class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> q{{root}};
while (!q.empty()) {
root = q.front(); q.pop();
if (root->right) q.push(root->right);
if (root->left) q.push(root->left);
}
return root->val;
}
};

參考資料:

https://leetcode.com/problems/find-bottom-left-tree-value/

https://leetcode.com/problems/find-bottom-left-tree-value/discuss/98779/Right-to-Left-BFS-(Python-%2B-Java)

https://leetcode.com/problems/find-bottom-left-tree-value/discuss/98786/verbose-java-solution-binary-tree-level-order-traversal