更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~
T:
题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
定义法
这道题目,竟然没有想出来如何用递归做,虽然也在最开始做了挣扎,还是没找到递归的切入点,只得从定义出发,先按照原二叉树,搞一个新的镜像,然后再搞个函数,对比两个树是否完全相同,貌似很麻烦,其实做起来,确实很麻烦。。。
code:
class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
/**
* T: 对称的二叉树
*
* 题目描述
* 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
*
* date: 2-15.12.9 20:36
* @author SSS
*
*/
public class Solution {
/**
* 先构造一个镜像,然后比较两个树是否相等
* @param pRoot
* @return
*/
boolean isSymmetrical(TreeNode pRoot){
boolean flag = true;
if (pRoot == null) {
return flag;
}
TreeNode newRoot = new TreeNode(0);
this.mirrorTree(pRoot, newRoot);
flag = this.isEqual(pRoot, newRoot);
return flag;
}
/**
* 生成二叉树pRoot的镜像二叉树
*
* 递归函数功能:把pRoot的val赋值给newRoot,然后新建左节点和右节点,分别递归
* @param pRoot
* @param newRoot
*/
public void mirrorTree(TreeNode pRoot, TreeNode newRoot) {
newRoot.val = pRoot.val;
if (pRoot.left != null) {
// 创建镜像树的右节点
TreeNode rightNewNode = new TreeNode(3);
newRoot.right = rightNewNode;
// 原二叉树的左节点与镜像树的右节点进行递归
this.mirrorTree(pRoot.left, rightNewNode);
} else {
newRoot.right = null;
}
if (pRoot.right != null) {
// 镜像树的左节点
TreeNode leftNewNode = new TreeNode(3);
newRoot.left = leftNewNode;
// 与原树的右节点进行递归
this.mirrorTree(pRoot.right, leftNewNode);
} else {
newRoot.left = null;
}
}
/**
* 判断两棵树是否相等
* @param pRoot
* @param newRoot
* @return
*/
public boolean isEqual(TreeNode pRoot, TreeNode newRoot) {
if (pRoot == null && newRoot == null) {
return true;
}
if (pRoot != null && newRoot != null && pRoot.val == newRoot.val) {
return this.isEqual(pRoot.left, newRoot.left) && this.isEqual(pRoot.right, newRoot.right);
} else {
return false;
}
}
}
递归法
这是在AC这道题目之后,还是不甘心,看到讨论版的那么多用递归做的,又苦思冥想起了递归,不负有心人,想明白了之后,就感觉很简单了。。。
在草稿纸上多画几层树结构,就能大致总结出比较规律。
规律如下:
一般的,比较完两个节点(设为节点
A
A
A和节点
B
B
B)之后,总是要在节点
A
A
A的左右节点和节点
B
B
B的左右节点之间进行比较,
A
A
A的左节点与
B
B
B的右节点比较,
A
A
A的右节点与
B
B
B的左节点比较,这样就形成了递归的形式。
代码写起来,就相当的简洁了。
code:
package niuke.sward2offer.isSymmetrical;
/**
* T: 对称的二叉树
*
* 题目描述
* 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
*
* date: 2-15.12.9 22:00
* @author SSS
*
*/
public class Solution2 {
boolean isSymmetrical(TreeNode pRoot){
boolean flag = true;
flag = this.varifySymmetrical(pRoot, pRoot);
return flag;
}
/**
* 判断两个节点的val是否相等;
* 如果相等,比较aNode.left/bNode.right 和 aNode.right/bNode.left是否相等,如此递归……
* @param aNode
* @param bNode
* @return
*/
public boolean varifySymmetrical(TreeNode aNode, TreeNode bNode) {
// 终止条件:两个节点都是null,说明都已经到了叶节点的子节点
if (aNode == null && bNode == null) {
return true;
}
// 当两者中有且只有一个为null,肯定不对称
if ((aNode == null && bNode != null) || (aNode != null && bNode == null)) {
return false;
}
// 两者val不相等,也不是对称
if (aNode.val != bNode.val) {
return false;
}
return this.varifySymmetrical(aNode.left, bNode.right) && this.varifySymmetrical(aNode.right, bNode.left);
}
}
更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~