100.相同的树
思路:
递归遍历二叉树
根据先序遍历的顺序,先访问根节点,再访问左子树,后访问右子树,而对于每个子树来说,又按照同样的访问顺序进行遍历
满足相同的树的条件为:
左节点、右节点、左子树、右子树完全相同即可
终止递归的且为true的情况:
- 如果p和q都为 n u l l p t r nullptr nullptr,则二叉树相同,返回true
- 如果p和q都不为 n u l l p t r nullptr nullptr且值是相等的,如果 l e f t left left和 r i g h t right right同时相同的话,则二叉树相同,返回true
其余的情况,二叉树都是不相同的,返回false
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == nullptr && q == nullptr) //p和q都为 nullptr,则二叉树相同,返回true
return true;
if ((p != nullptr && q != nullptr)&&(p->val == q->val)) //p和q都不为nullptr且值是相等的
return isSameTree(p->right, q->right) && isSameTree(p->left, q->left);//递归
else
return false;//其他情况都是false
}
};
if-else也可以用三目运算法——简化成一句代码
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
return (p!=nullptr && q!=nullptr)?(p->val==q->val) && (isSameTree(p->left, q->left) && isSameTree(p->right, q->right)):p==nullptr && q==nullptr;
}
};
注: n u l l p t r nullptr nullptr是C++ 11 11 11中的关键字,表示空指针。
101. 对称二叉树
题意:
从题目下方的(进阶)可以看出:可以用递归(因为有LeetCode 100铺垫,所以先看递归)
递归:
在遍历的时候设置两个指针,一个向左一个向右同时遍历。
- 首先判断根节点是否为空,如果根节点为空,那么自然对称(我忘了,所以wa了)true
- 如果左、右节点同时为空,也是对称的。true
- 如果左右节点只有一个为空,就不对称。false
- 一个向左一个向右同时遍历,递归判断 :
(左子树的左孩子的节点值 == 右子树的右孩子的节点值 && 右子树的左孩子的节点值 == 左子树的右孩子的节点值)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root == NULL) //根节点为空,则是镜像,为true
return true;
return istrue(root->left, root->right);
}
bool istrue(TreeNode* l, TreeNode* r) {
if(l == NULL && r == NULL)//左右节点均为空,则是镜像,为true
return true;
if((l != NULL && r == NULL)||(l == NULL && r != NULL)) //如果左右子树只有一个为空,则不对称,为false
return false;
if(l -> val == r -> val)//一个向左一个向右同时遍历,
//递归判断 (左子树的左孩子的节点值 == 右子树的右孩子的节点值 && 右子树的左孩子的节点值 == 左子树的右孩子的节点值)
return (istrue(l -> left, r -> right) && istrue(l -> right, r -> left));
return false;
}
};