题目描述
给定一个二叉树,在树的最后一行找到最左边的值。
题解
以下分析来自513. 找树左下角的值:【递归】【迭代】详解
题解1:递归法
那么如果找最左边的呢?可以使用前序遍历,这样才先优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
注意: 首先判断根结点的左子树首否为空,更新树的最大高度,并以树的最大高度来判断是否需要更新最后一行最左边的值。
递归三部曲:
- 确定递归函数的参数和返回值
参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。 这里就不需要返回值了,所以递归函数的返回类型为void。
本题还需要类里的两个全局变量,maxLen用来记录最大深度,maxleftValue记录最大深度最左节点的数值。
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);
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为树的宽度。