如果需要遍历整棵树,递归函数就不能有返回值。如果需要遍历某一条固定路线,递归函数就一定要有返回值!
101. 对称二叉树
else if (left->val != right->val) return false
注意判断特殊情况
类似题目:
100.相同的树
572. 另一棵树的子树
// 其中isSameTree就是判断相同的树的逻辑
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if (root == nullptr && subRoot != nullptr) return false;
else if (root == nullptr && subRoot == nullptr) return true;
return isSameTree(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
这里非常巧妙,调用自身来判断(root->left, subRoot)和(root->right, subRoot)
104. 二叉树的最大深度
depth = 1 + max(leftdepth, rightdepth);
111. 二叉树的最小深度
// 当一个左子树为空,右不为空,这时并不是最低点
if (node->left == NULL && node->right != NULL) {
return 1 + rightDepth;
}
// 当一个右子树为空,左不为空,这时并不是最低点
if (node->left != NULL && node->right == NULL) {
return 1 + leftDepth;
}
int result = 1 + min(leftDepth, rightDepth);
222. 完全二叉树的节点个数
注意完全二叉树的节点总数的计算公式。
if (depthLeft == depthRight) {
return (2 << depthLeft) - 1;
}
110. 平衡二叉树
这道题还是不能自己独立的写出来递归解法。一直觉得这道题真不是“简单”。
对理解递归的过程理解很有帮助
还是需要多理几遍递归的执行过程。
class Solution {
public:
int getDepth(TreeNode* root) {
if (root == nullptr) return 0;
int depthLeft = getDepth(root->left);
if (depthLeft == -1) return -1;
int depthRight = getDepth(root->right);
if (depthRight == -1) return -1;
int result = 0;
if (abs(depthLeft - depthRight) > 1) return -1;
else {
return 1 + max(depthLeft, depthRight);
}
}
bool isBalanced(TreeNode* root) {
int result = getDepth(root);
return result == - 1 ? false : true;
}
};
257. 二叉树的所有路径
因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进path中。
然后是递归和回溯的过程,上面说过没有判断cur是否为空,那么在这里递归的时候,如果为空就不进行下一层递归了。
回溯和递归是一一对应的,有一个递归,就要有一个回溯
class Solution {
public:
void backtracking(TreeNode* root, vector<string>& ans, vector<int>& vec) {
vec.push_back(root->val); // 前序遍历
if (root->left == nullptr && root->right == nullptr) {
string str;
int len = vec.size();
for (int i = 0; i < len - 1; i++) {
str += std::to_string(vec[i]) + "->";
}
str += std::to_string(vec[len - 1]);
ans.push_back(str);
}
if (root->left) { // 判空
backtracking(root->left, ans, vec);
vec.pop_back(); // 回溯和递归一一绑定
}
if (root->right) {
backtracking(root->right, ans, vec);
vec.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<int> vec;
vector<string> ans;
backtracking(root, ans, vec);
return ans;
}
};
404.左叶子之和
定义:如果左节点不为空,且左节点没有左右孩子,那么这个节点的左节点就是左叶子
如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,判断代码如下:
if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
左叶子节点处理逻辑
}