树的学习先从一些比较简单的入门题开始,考察的还是对于树的递归形式的理解。
LeetCode面试题 04.04. 检查平衡性 && 剑指 Offer 55 - II. 平衡二叉树
实现一个函数,检查二叉树是否平衡。在这个问题中,平衡树的定义如下:任意一个节点,其两棵子树的高度差不超过 1(此题本人的解法也包含了求二叉树的最大深度)。
class Solution {
public:
bool res = true;
int maxDepth(TreeNode* root) {
if(root == NULL) return 0;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
if(abs(left - right) > 1) res = false;
return max(left, right) + 1;
}
bool isBalanced(TreeNode* root) {
if(root == NULL) return true;
maxDepth(root);
return res;
}
};
LeetCode剑指 Offer 28. 对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root==NULL)//根节点为空
return true;
return judge(root->left, root->right);
}
bool judge(TreeNode* p,TreeNode* q){
if(p == NULL && q == NULL) //如果两节点都为空
return true;
if(p == NULL || q == NULL) //如果两节点只有一个为空
return false;
if(p->val != q->val) //如果两节点值不相等
return false;
bool temp = judge(p->left, q->right); //先判断两侧
if(temp == false) //两侧不对称,直接返回false
return false;
return judge(p->right, q->left); //两侧对称,判断中间是否对称
}
};
LeetCode404. 左叶子之和
计算给定二叉树的所有左叶子之和。(计数类型的题目,关键点在于从底向上进行计算)。
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root == NULL) return 0;
int res = 0;
if(root->left != NULL){
if(root->left->left == NULL && root->left->right == NULL)
res += root->left->val; //找到左叶子节点
else res += sumOfLeftLeaves(root->left);
}
if(root->right != NULL) res += sumOfLeftLeaves(root->right);
return res;
}
};
LeetCode111. 二叉树的最小深度
给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
class Solution {
public:
int minDepth(TreeNode* root) {
if (!root) return 0; //递归结束
int left = minDepth(root->left); //计算左子树的高度
int right = minDepth(root->right); //计算右子树的高度
if (!left || !right) return left + right + 1; //如果有一个空,则+1
return min(left, right) + 1; //否则最小值+1
}
};
LeetCode257. 二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。(此题是二叉树先序遍历的变形)
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> res;
string str = "";
dfs(root, res, str);
return res;
}
void dfs(TreeNode* root, vector<string>& res, string str){
if(root == NULL) return ;
if(root->left == NULL && root->right == NULL){
str += to_string(root->val);
res.push_back(str);
}
str += to_string(root->val) + "->";
dfs(root->left, res, str);
dfs(root->right, res, str);
}
};
LeetCode剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
LeetCode剑指 Offer 68 - II. 二叉树的最近公共祖先
给定一个二叉树/二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
class Solution {
public:
//二叉搜索树 根据性质二叉搜索相应的左右子树就完事了
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL) return NULL;
if(root->val > p->val && root->val > q->val)
return lowestCommonAncestor(root->left, p, q);
else if(root->val < p->val && root->val < q->val)
return lowestCommonAncestor(root->right, p, q);
else return root;
}
//普通二叉树 需要遍历完左右子树,不同的是节点可能出现在同一颗左子树或右子树上
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL || root == p || root == q) return root;
//左子树寻找p, q
TreeNode* left = lowestCommonAncestor(root->left, p, q);
//右子树寻找p, q
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left == NULL) return right;
if(right == NULL) return left;
return root;
}
};