LeetCode:513. 找树左下角的值(中等)

题目描述

给定一个二叉树,在树的最后一行找到最左边的值。
示例

题解

以下分析来自513. 找树左下角的值:【递归】【迭代】详解

题解1:递归法

那么如果找最左边的呢?可以使用前序遍历,这样才先优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。

注意: 首先判断根结点的左子树首否为空,更新树的最大高度,并以树的最大高度来判断是否需要更新最后一行最左边的值。
递归三部曲:

  1. 确定递归函数的参数和返回值
    参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。 这里就不需要返回值了,所以递归函数的返回类型为void。
    本题还需要类里的两个全局变量,maxLen用来记录最大深度,maxleftValue记录最大深度最左节点的数值。
int maxLen = INT_MIN;   // 全局变量 记录最大深度(求最大值时初始值赋逻辑最小值)
int maxleftValue;       // 全局变量 最大深度最左节点的数值
void traversal(TreeNode* root, int leftLen)

如果需要遍历整颗树,递归函数就不能有返回值。如果需要遍历某一条固定路线,递归函数就一定要有返回值!

  1. 确定终止条件
    当遇到叶子节点的时候需要更新最大深度。
if (root->left == NULL && root->right == NULL) {
    if (leftLen > maxLen) {
        maxLen = leftLen;           // 更新最大深度
        maxleftValue = root->val;   // 最大深度最左面的数值 
    }
    return;
}
  1. 确定单层递归的逻辑
    在找最大深度的时候,递归的过程中依然要使用回溯。
                    // 中
if (root->left) {   // 左
    leftLen++; // 深度加一     
    traversal(root->left, leftLen);
    leftLen--; // 回溯,深度减一
}
if (root->right) { // 右
    leftLen++; // 深度加一
    traversal(root->right, leftLen);
    leftLen--; // 回溯,深度减一
}
return;

完整代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int maxLen = INT_MIN;
    int maxleftValue;
    void traversal(TreeNode* root, int leftLen) {
        if (root->left == NULL && root->right == NULL) {
            if (leftLen > maxLen) {
                maxLen = leftLen;
                maxleftValue = root->val;
            }
            return;
        }
        if (root->left) {
            leftLen++;
            traversal(root->left, leftLen);
            cout << "leftmaxleftValue=" << maxleftValue << endl;
            leftLen--; // 回溯
        }
        if (root->right) {//当左右子结点都有时,由于先进入左子结点,更新了树的最大深度,此时最后一层最左边结点值不会更新
            leftLen++;
            //cout << "rightLen" << leftLen << endl;
            traversal(root->right, leftLen);
            cout << "rightmaxleftValue=" << maxleftValue << endl;
            leftLen--; // 回溯 
            //cout << "rightLen" << leftLen << endl;
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        traversal(root, 0);
        return maxleftValue;
    }
};

复杂度分析

  • 时间复杂度:O(N), N为树的结点数。
  • 空间复杂度: O(1)。

题解2:宽度优先搜索BFS(Breadth-First Search)

从上到下, 从左到右, 层序遍历每一行所有结点。只需要记录最后一行第一个节点的数值就可以了。

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;//在某一阶段存储相同高度结点值
        if (root != NULL) que.push(root);
        int result = 0;
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (i == 0) result = node->val; // 记录最后一行第一个元素
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return result;
    }
};

复杂度分析

  • 时间复杂度:O(N), N为树的结点数。
  • 空间复杂度: O(w), w为树的宽度。

参考

513. 找树左下角的值:【递归】【迭代】详解
BFS改进法,简单易懂,接近双百。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值