①二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回它的最小深度 2.
1.首先判断如果根节点为空,则深度肯定为0;如果左、右节点都为空,则只存在根节点,深度返回1;如果当前节点的左子树为空,则遍历右子树,反之则遍历左子树,然后递归遍历每个节点找出最小深度:
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == NULL) //根节点为空,返回0
return 0;
if (root->left == NULL && root->right == NULL) //左、右节点同时为空,则为叶子节点,返回1
return 1;
if (root->left == NULL) //如果左子树为空,则遍历右子树
return 1 + minDepth(root->right);
if (root->right == NULL) //反之遍历左子树
return 1 + minDepth(root->left);
return 1 + min(minDepth(root->left), minDepth(root->right)); //递归遍历,找出最小深度
}
};
②路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22
,
5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1
返回 true
, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2
。
1.采用深度优先DFS的思想来遍历每一条完整的路径,也就是利用递归不停找子节点的左右子节点,而调用递归函数的参数只有当前节点和sum值。首先根节点为空则返回false;如果左、右子节点为空,而根节点的值等于sum则返回true,若不等于则返回false;接着进行递归,由函数的返回值是true/false,所以从两边节点开始递归,将递归的结果用||运算符返回,只要两者中的一个为true则为true。递归遍历时sum应为sum减去当前节点值:
class Solution {
public:
bool hasPathSum(TreeNode *root, int sum) {
if (root == NULL) return false; //根节点为空,返回false
//左、右节点都为空且根节点数值等于sum,返回true
if (root->left == NULL && root->right == NULL && root->val == sum ) return true;
//左、右节点都为空且根节点数值不等于sum,返回false
if (root->left == NULL && root->right == NULL && root->val != sum ) return false;
//分别对左、右节点进行递归遍历,当前sum应为sum减去当前节点值,同时只要两者有一个返回true即为true
return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
}
};
2.与上述思路差不多,不过将递归函数改变为一个自定义的函数,其中添加一个新参数(各节点数值之和)tmp,将递归后的tmp与sum作比较,如果相等,则返回true,否则返回false:
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == NULL) return false;
return check(root, sum, 0);
}
bool check(TreeNode* p, int sum, int tmp)
{
if (p == NULL) return false; //当前传入节点为空,返回false
tmp += p->val; //节点之和
if (!p->left && !p->right && tmp == sum) return true;
if (!p->left && !p->right && tmp != sum) return false;
bool lhs = false, rhs = false; //标记两个变量,分别记录左、右节点遍历的结果
if (p->left) lhs = check(p->left, sum, tmp);
if (p->right) rhs = check(p->right, sum, tmp);
return lhs || rhs; //得出结果,有一边为true即为true
}
};