LeetCode513. Find Bottom Left Tree Value題解

1. 題目描述

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

2. 樣例

這裏寫圖片描述

3. 分析

這道題的思路和LeetCode515的思路很像,都是BFS和層次遍歷的算法。有了之前題目的經驗,這裏我仍然採取兩種思路解這道題:遞歸與非遞歸。

3.1. 非遞歸法

層次遍歷法,題目描述是要求找到最後一行的最左面的元素,首先我們得找到最後一行,於是仍然使用兩個隊列進行遍歷,分別保存:已經訪問的節點和節點所在的層數。
由於我們實現的層次遍歷是每一次都先從節點的左孩子壓入隊列,緊接着纔是右孩子,所以其實樹的每一層最開始壓入隊列的元素就是最左面的元素。
實現方式就是:設置兩個變量記錄當前節點所在層數和上一次訪問的節點所在層數,如果當前的層數高於上一次的層數,說明就開始訪問新的一層了,那麼此時的節點就是該層最左面的節點。我們只要返回最後那層的節點即可。
這裏寫圖片描述

3.2. 遞歸法

說實話,這個想法我是有的,不過寫起來有的複雜,看了討論區大佬的算法,簡單清晰。
多態:新寫了一個同名的函數,這裏面有一個call by reference的參數maxDepth和一個call by value的參數depth。前者隨着訪問值在變化,一直記錄着已經經歷過的最大層數,後者則是當前節點的層數。由於遞歸仍然是從左孩子先開始,所以只有當maxDepth < depth的時候纔是進入新的一層,此時節點就是新的一層最左面的節點,接下來使用相同的方法,返回該節點的值。
這裏寫圖片描述

4. 源碼

4.1. 非遞歸法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*>tree;
        queue<int>level;
        TreeNode* current_node = root;
        int result = -1;
        int current_level = 0;
        int last_level = -1;
        if (current_node != NULL) {
            result = current_node->val;
            tree.push(current_node);
            level.push(current_level);
            while(!tree.empty()) {
                current_node = tree.front();
                tree.pop();
                current_level = level.front();
                level.pop();
                if (current_node->left != NULL) {
                    tree.push(current_node->left);
                    level.push(current_level+1);
                }
                if (current_node->right != NULL) {
                    tree.push(current_node->right);
                    level.push(current_level+1);
                }
                if (current_level > last_level) {
                    result = current_node->val;
                }
                last_level = current_level;
            }
        }
        return result;
    }
};

4.2. 遞歸法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void findBottomLeftValue(TreeNode* root, int& maxDepth, int& leftVal, int depth) {
        if (root == NULL) {
            return;
        }

        findBottomLeftValue(root->left, maxDepth, leftVal, depth+1);
        findBottomLeftValue(root->right, maxDepth, leftVal, depth+1);

        //由於先從左邊開始遞歸,並且maxDepth可以記錄當前最大深度,所以只有觸發此機制的時候纔是新的一層的開始
        if (depth > maxDepth) {
            maxDepth = depth;
            leftVal = root->val;
        }
    }


    int findBottomLeftValue(TreeNode* root) {
        int maxDepth = 0;
        int leftVal = root->val;
        findBottomLeftValue(root, maxDepth, leftVal, 0);
        return leftVal;
    }
};

5. 心得

使用BFS,遞歸雖好,但是難點在於如何將原問題進行分解以及找到合適的遞歸出口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章