算法1
(二叉树,递归) $O(n)$
递归判断两个子树是否互为镜像。
两个子树互为镜像当且仅当:
- 两个子树的根节点值相等;
- 第一棵子树的左子树和第二棵子树的右子树互为镜像,且第一棵子树的右子树和第二棵子树的左子树互为镜像;
时间复杂度
从上到下每个节点仅被遍历一遍,所以时间复杂度是 $O(n)$。
C++ 代码
/**
* 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) {
return !root || dfs(root->left, root->right);
}
bool dfs(TreeNode*p, TreeNode*q)
{
if (!p || !q) return !p && !q;
return p->val == q->val && dfs(p->left, q->right) && dfs(p->right, q->left);
}
};
算法2
(迭代) $O(n)$
用栈模拟递归,对根节点的左子树,我们用中序遍历;对根节点的右子树,我们用反中序遍历。
则两个子树互为镜像,当且仅当同时遍历两课子树时,对应节点的值相等。
时间复杂度
树中每个节点仅被遍历一遍,所以时间复杂度是 $O(n)$。
C++ 代码
/**
* 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) return true;
stack<TreeNode*> left, right;
TreeNode *lc = root->left;
TreeNode *rc = root->right;
while(lc || rc || left.size())
{
while (lc && rc)
{
left.push(lc), right.push(rc);
lc = lc->left, rc = rc->right;
}
if (lc || rc) return false;
lc = left.top(), rc = right.top();
left.pop(), right.pop();
if (lc->val != rc->val) return false;
lc = lc->right, rc = rc->left;
}
return true;
}
};
方法一的代码太优美了
方法一太赞了!!
判断条件绝了,y总牛皮
这个判断条件写得真好啊
谢谢hh
if (!p || !q) return p==q; 也可以
我就是这么写的awa
yls, 递归的空间复杂度是$O(n)$ 还是 $O(h)$呀?
另外 $O(h)$ 和 $O(logn)$ 是等价的吧?
普通二叉树的高度最坏是 $O(n)$,不是 $O(logn)$。
我终于明白啦!感谢!
if (!p || !q) return !p && !q;
这里为啥不能直接判断p,q同时为空,返回true
这里不仅可以判断这种情况,还能判断一个空一个不空,这样也是不对称的,会返回false。
谢谢大佬
主函数可以直接return dfs(root,root);
对滴,可以的。
dfs()函数名是代表深度优先搜索吗?
对滴,全称是 Depth-first search