关于树的递归问题,永远考虑两方面:返回条件和子问题
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
if (p == NULL && q == NULL)
{
return true;
}
if (p == NULL || q == NULL)
{
return false;
}
if (p->val != q->val)
{
return false;
}
return isSameTree(p->left, q->left)
&& isSameTree(p->right, q->right);
}
思路:判断单值的条件,就是让父节点的值与两个孩子的值相等
具体方法:
bool isUnivalTree(struct TreeNode* root)
{
if (root == NULL)
{
return true;
}
if (root->left && root->val != root->left->val)
{
return false;
}
if (root->right && root->val != root->right->val)
{
return false;
}
return isUnivalTree(root->left)
&& isUnivalTree(root->right);
}
思路:因为要用左子树的左支(右支)和右子树的右支(左支)进行比较,所以再创建一个子函数接受两个参数。
具体方法:
bool _isSymmetric(struct TreeNode* left, struct TreeNode* right)
{
if (left == NULL && right == NULL)
{
return true;
}
if (left == NULL || right == NULL)
{
return false;
}
if (left->val != right->val)
{
return false;
}
return _isSymmetric(left->left, right->right)
&& _isSymmetric(left->right, right->left);
}
bool isSymmetric(struct TreeNode* root)
{
return _isSymmetric(root->left, root->right);
}
首先,这题要注意的是,它要求动态开辟一个数组,将二叉树的值以前序遍历的顺序放入,最后再返回该数组,所以它跟我们之前直接前序遍历还是不一样的,变得更加复杂了。
具体实现思路:
传入i时,会造成内存错误,如下图:
void _preorderTraversal(struct TreeNode* root, int* a, int* pi)
{
if (root == NULL)
{
return;
}
a[(*pi)++] = root->val;
_preorderTraversal(root->left, a, pi);
_preorderTraversal(root->right, a, pi);
}
int BTreeSize(struct TreeNode* root)
{
return root == NULL ? 0 : BTreeSize(root->left) + BTreeSize(root->right) + 1;
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
*returnSize = BTreeSize(root);
int* a = (int*)malloc(*returnSize * sizeof(int));
int i = 0;
_preorderTraversal(root, a, &i);
return a;
}
思路:这题可以复用 100. 相同的树 这题的代码,来转化为比较root树的任意一棵子树,是否存在与subRoot树相等,如果相等,则代表是它的子树
具体方法:
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
if (p == NULL && q == NULL)
{
return true;
}
if (p == NULL || q == NULL)
{
return false;
}
if (p->val != q->val)
{
return false;
}
return isSameTree(p->left, q->left)
&& isSameTree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
if (root == NULL)
{
return false;
}
if (isSameTree(root, subRoot))
{
return true;
}
return isSubtree(root->left, subRoot)
|| isSubtree(root->right, subRoot);
}