513.找树左下角的值
最后一行的最左边的值。所以目标就是:在树的最后一行找到最左边的值。最后一行:找深度最大的叶子结点;最左边:采用任何顺序的遍历都可以,因为左都在右的左边。
1、确定递归函数的参数和返回值
需要类里的两个全局变量,maxDepth用来记录最大深度,result记录最大深度最左节点的数值。
2、确定终止条件
遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。
3、确定单层递归的逻辑
在找最大深度的时候,递归的过程中依然要使用回溯
class Solution {
public:
int MaxDeep = INT_MIN;
int result;
void traversal(TreeNode* root, int deep) {
if (root->left == NULL && root->right == NULL) {
if (deep > MaxDeep) {
MaxDeep = deep;
result = root->val;
}
return;
}
if (root->left) {
deep++;
traversal(root->left, deep);
deep--;
}
if (root->right) {
deep++;
traversal(root->right, deep);
deep--;
}
return;
}
int findBottomLeftValue(TreeNode* root) {
if (root == NULL)
return 0;
traversal(root, 0);
return result;
}
};
112. 路径总和
本题前中后序都可以,无所谓,因为中节点也没有处理逻辑
1、确定递归函数的参数和返回类型
参数:需要二叉树的根节点,还需要一个计数器

2、确定终止条件
if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
if (!cur->left && !cur->right) return false; // 遇到叶子节点而没有找到合适的边,直接返回
3、确定单层递归的逻辑
因为终止条件是判断叶子节点,所以递归的过程中就不要让空节点进入递归了。递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。
下面是整体代码:(要注意的是,这个函数没有减去根节点的值,所以在传入目标值的时候要减去根节点的值)。(还要注意:这里的回溯只有在返回false时才起作用,返回true时就不回溯了,因为没必要了,这一点观察代码回溯放置的位置就知道了)。
class Solution {
public:
bool traversal(TreeNode* root, int targetSum) {
if (root->left == NULL && root->right == NULL && targetSum == 0)
return true;
if (root->left == NULL && root->right == NULL && targetSum != 0)
return false;
if (root->left) {
targetSum -= root->left->val;
if (traversal(root->left, targetSum))
return true;
targetSum += root->left->val;
}
if (root->right) {
targetSum -= root->right->val;
if (traversal(root->right, targetSum))
return true;
targetSum += root->right->val;
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if (root == NULL)
return false;
return traversal(root, targetSum - root->val);
}
};
106.从中序与后序遍历序列构造二叉树
这里直接使用卡哥的板书:
1、后续数组为0,空节点;
2、后续数组最后一个元素为根节点(遍历过程中就是子树的根节点);
3、寻找中序数组中的这个元素作为切割点,左边是左子树,右边是右子树;
4、切割中序数组
5、切割后序数组
6、递归处理做区间和右区间


板书也截一下,这个很直观,便于理解:
class Solution {
private:
TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) {
if (postorder.size() == 0)
return NULL;
int rootval = postorder[postorder.size() - 1];
TreeNode* root = new TreeNode(rootval);
// 叶子节点
if (postorder.size() == 1)
return root;
// 切割数组
int delimiterIndex = 0;
for (delimiterIndex; delimiterIndex < inorder.size();
delimiterIndex++) {
if (inorder[delimiterIndex] == rootval)
break;
}
// 这里统一使用左闭右开
vector<int> leftinorder(inorder.begin(),
inorder.begin() + delimiterIndex);
vector<int> rightinorder(inorder.begin() + delimiterIndex + 1,
inorder.end());
// postorder 舍弃末尾元素,因为这个元素就是中间节点,已经用过了
postorder.resize(postorder.size() - 1);
vector<int> leftpostorder(postorder.begin(),
postorder.begin() + leftinorder.size());
vector<int> rightpostorder(postorder.begin() + leftinorder.size(),
postorder.end());
root->left = traversal(leftinorder, leftpostorder);
root->right = traversal(rightinorder, rightpostorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0)
return NULL;
return traversal(inorder, postorder);
}
};

1554

被折叠的 条评论
为什么被折叠?



